From 28eac83ec5e7aec62fdfacd6285ded186cb1df65 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 28 Jul 2006 10:21:47 +0200 Subject: [PATCH 001/235] Add query_len variable to st_query, avoids a lot of strlen and allows better allocation of dynamic strings Tune some inital allocations of dynamic strings --- client/mysqltest.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3b55ebb2f8b..2b0fcb0faa4 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -362,7 +362,7 @@ Q_COMMENT_WITH_COMMAND struct st_query { char *query, *query_buf,*first_argument,*last_argument,*end; - int first_word_len; + int first_word_len, query_len; my_bool abort_on_error, require_file; match_err expected_errno[MAX_EXPECTED_ERRORS]; uint expected_errors; @@ -758,12 +758,13 @@ static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP))) die(NullS); tmp[stat_info.st_size] = 0; - init_dynamic_string(&res_ds, "", 0, 65536); + init_dynamic_string(&res_ds, "", stat_info.st_size+256, 256); if (eval_result) { do_eval(&res_ds, tmp, FALSE); - res_ptr = res_ds.str; - if ((res_len = res_ds.length) != ds->length) + res_ptr= res_ds.str; + res_len= res_ds.length; + if (res_len != ds->length) { res= RESULT_LENGTH_MISMATCH; goto err; @@ -783,9 +784,9 @@ err: str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr, res_len); + dynstr_free(&res_ds); my_free((gptr) tmp, MYF(0)); my_close(fd, MYF(MY_WME)); - dynstr_free(&res_ds); DBUG_RETURN(res); } @@ -1183,7 +1184,7 @@ static void do_exec(struct st_query *query) die("Missing argument in exec"); query->last_argument= query->end; - init_dynamic_string(&ds_cmd, 0, strlen(cmd)+256, 256); + init_dynamic_string(&ds_cmd, 0, query->query_len+256, 256); /* Eval the command, thus replacing all environment variables */ do_eval(&ds_cmd, cmd, TRUE); cmd= ds_cmd.str; @@ -1306,7 +1307,7 @@ int var_query_set(VAR* var, const char *query, const char** query_end) MYSQL_FIELD *fields= mysql_fetch_fields(res); #endif - init_dynamic_string(&result, "", 16384, 65536); + init_dynamic_string(&result, "", 2048, 2048); lengths= mysql_fetch_lengths(res); for (i=0; i < mysql_num_fields(res); i++) { @@ -1498,7 +1499,7 @@ void do_system(struct st_query *command) if (strlen(command->first_argument) == 0) die("Missing arguments to system, nothing to do!"); - init_dynamic_string(&ds_cmd, 0, strlen(command->first_argument) + 64, 256); + init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256); /* Eval the system command, thus replacing all environment variables */ do_eval(&ds_cmd, command->first_argument, TRUE); @@ -1552,7 +1553,7 @@ int do_echo(struct st_query *command) ds= &ds_res; - init_dynamic_string(&ds_echo, "", 256, 256); + init_dynamic_string(&ds_echo, "", command->query_len, 256); do_eval(&ds_echo, command->first_argument, FALSE); dynstr_append_mem(ds, ds_echo.str, ds_echo.length); dynstr_append_mem(ds, "\n", 1); @@ -3205,6 +3206,7 @@ int read_query(struct st_query** q_ptr) q->record_file[0]= 0; q->require_file= 0; q->first_word_len= 0; + q->query_len= 0; q->type= Q_UNKNOWN; q->query_buf= q->query= 0; @@ -3255,6 +3257,7 @@ end: p++; q->first_argument= p; q->end= strend(q->query); + q->query_len= (q->end - q->query); parser.read_lines++; DBUG_RETURN(0); } @@ -4723,7 +4726,7 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags) */ if (command->type == Q_EVAL) { - init_dynamic_string(&eval_query, "", 16384, 65536); + init_dynamic_string(&eval_query, "", command->query_len+256, 1024); do_eval(&eval_query, command->query, FALSE); query = eval_query.str; query_len = eval_query.length; @@ -4742,7 +4745,7 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags) */ if (command->record_file[0]) { - init_dynamic_string(&ds_result, "", 16384, 65536); + init_dynamic_string(&ds_result, "", 1024, 1024); ds= &ds_result; } else @@ -5209,7 +5212,7 @@ int main(int argc, char **argv) memset(&master_pos, 0, sizeof(master_pos)); - init_dynamic_string(&ds_res, "", 0, 65536); + init_dynamic_string(&ds_res, "", 65536, 65536); init_dynamic_string(&ds_progress, "", 0, 2048); parse_args(argc, argv); @@ -5404,7 +5407,8 @@ int main(int argc, char **argv) } /* fix up query pointer if this is first iteration for this line */ if (q->query == q->query_buf) - q->query += q->first_word_len; + q->query+= q->first_word_len; + /* run_query() can execute a query partially, depending on the flags. QUERY_SEND flag without QUERY_REAP tells it to just send the From 7e5ed1893cc63d72ec2db85c9b17ce4a0399fa3b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 12:33:59 +0200 Subject: [PATCH 002/235] Add missing semicolon in csv test mysql-test/t/csv.test: Add missing semicolon --- mysql-test/t/csv.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 9ba99167ab9..f17f90c71a5 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1295,7 +1295,7 @@ SELECT fld3 FROM t2; # DROP TABLE t1; -ALTER TABLE t2 RENAME t1 +ALTER TABLE t2 RENAME t1; # # Drop and recreate From 77c97139cde560d6af60a762c15e47c1490b8084 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 12:35:30 +0200 Subject: [PATCH 003/235] Add missing semicolon in query_cache test mysql-test/r/query_cache.result: Add missing semicolon mysql-test/t/query_cache.test: Add missing semicolon --- mysql-test/r/query_cache.result | 2 +- mysql-test/t/query_cache.test | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 27a84f90126..53f62dc91b4 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -934,7 +934,7 @@ abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba flush query cache; drop table t1, t2; -set GLOBAL query_cache_size=1355776 +set GLOBAL query_cache_size=1355776; #; flush status; CREATE TABLE t1 ( diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index 2c94fe63c04..67c4c4cb20b 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -699,7 +699,7 @@ select a from t1; flush query cache; drop table t1, t2; -set GLOBAL query_cache_size=1355776 +set GLOBAL query_cache_size=1355776; # From 01b65e9032ff3502470ebf8fb7082ab6317adc79 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 13:01:07 +0200 Subject: [PATCH 004/235] Remove spurios junk in result file caused by previous missing semicolon --- mysql-test/r/csv.result | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 04f0636d400..00086684774 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -4913,8 +4913,7 @@ bonfire Colombo nondecreasing DROP TABLE t1; -ALTER TABLE t2 RENAME t1 -#; +ALTER TABLE t2 RENAME t1; DROP TABLE t1; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, From 12a6874af18ca3a44ec77fc8161c206843425598 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 13:02:28 +0200 Subject: [PATCH 005/235] Remove spurious printout in result file caused by previous missing semicolon --- mysql-test/r/query_cache.result | 1 - 1 file changed, 1 deletion(-) diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index 53f62dc91b4..f9c332138d2 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -935,7 +935,6 @@ zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazy flush query cache; drop table t1, t2; set GLOBAL query_cache_size=1355776; -#; flush status; CREATE TABLE t1 ( `date` datetime NOT NULL default '0000-00-00 00:00:00', From f21668a90f4478bd1f485ccaba74a386206f361b Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 13:03:17 +0200 Subject: [PATCH 006/235] Add missing semicolon to wait_timeout test mysql-test/t/wait_timeout.test: Add missing semicolon --- mysql-test/t/wait_timeout.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test index dbd792e48d8..bdff72cdc76 100644 --- a/mysql-test/t/wait_timeout.test +++ b/mysql-test/t/wait_timeout.test @@ -55,7 +55,7 @@ select 2; select 3; # Disconnect so that we will not be confused by a future abort from this # connection. -disconnect default +disconnect default; # # Do the same test as above on a TCP connection From a7ec90633cf0a18fc0ca71a3b8c15cd64c75a3d0 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 18:11:19 +0200 Subject: [PATCH 007/235] Add missing delimiter in subselect test mysql-test/r/subselect.result: Add missing semicolon delimiter and junk caused by that mysql-test/t/subselect.test: Add missing semicolon delimiter --- mysql-test/r/subselect.result | 3 +-- mysql-test/t/subselect.test | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 75a9b422691..ec180a28188 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2717,8 +2717,7 @@ select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); ERROR 21000: Operand should contain 2 column(s) -drop table t1 -#; +drop table t1; CREATE TABLE `t1` ( `itemid` bigint(20) unsigned NOT NULL auto_increment, `sessionid` bigint(20) unsigned default NULL, diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 8916a5cec6d..ec314019492 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1728,7 +1728,7 @@ select (select a from t1) = (1,2); select (1,2,3) = (select * from t1); -- error 1241 select (select * from t1) = (1,2,3); -drop table t1 +drop table t1; # # Item_int_with_ref check (BUG#10020) From fddfab90d4859a74338285224514741bd3dbed4d Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 19:36:11 +0200 Subject: [PATCH 008/235] Change faulty delimiter ; to | --- mysql-test/t/sp.test | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 99f3bbbbd14..4d0a0d24003 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -2944,11 +2944,11 @@ begin end| --disable_parsing --replace_regex /table_id: [0-9]+/table_id: #/ -show binlog events; -show storage engines; -show master status; -show slave hosts; -show slave status; +show binlog events| +show storage engines| +show master status| +show slave hosts| +show slave status| --enable_parsing call bug4902()| From ff99e042e478218cd2d76462905c5f5099630abd Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 29 Jul 2006 19:38:46 +0200 Subject: [PATCH 009/235] Change faulty delimiter ; to | and remove junk in result file caused by that mysql-test/t/sp_notembedded.test: Change faulty delimiter ; to | --- mysql-test/r/sp_notembedded.result | 3 +-- mysql-test/t/sp_notembedded.test | 12 ++++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index a15f5013ef6..b620c77383c 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -76,8 +76,7 @@ flush status| flush query cache| delete from t1| drop procedure bug3583| -drop table t1; -#| +drop table t1| drop procedure if exists bug6807| create procedure bug6807() begin diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test index 28abf448089..6335ad55606 100644 --- a/mysql-test/t/sp_notembedded.test +++ b/mysql-test/t/sp_notembedded.test @@ -19,11 +19,11 @@ begin show grants for 'root'@'localhost'; end| --disable_parsing -show binlog events; -show storage engines; -show master status; -show slave hosts; -show slave status; +show binlog events| +show storage engines| +show master status| +show slave hosts| +show slave status| --enable_parsing call bug4902()| @@ -110,7 +110,7 @@ flush status| flush query cache| delete from t1| drop procedure bug3583| -drop table t1; +drop table t1| # # BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY From 5d39c1c64f7309754f6e0b40c80f9269818317c3 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Jul 2006 17:57:15 +0200 Subject: [PATCH 010/235] Improve and fix bugs in 'read_line' function of mysqltest client/mysqltest.c: Fix bugs in 'read_line' function, add better comments and some DBUG printouts Add do_delimiter function so the "delimiter" command is parsed better, it should not be allowed to have emtpy delimiter Add checks that disable/enable_pasring is not used when it's already disabled or enabled. Don't allow mysqltest to end with parsing disabled Add function 'convert_to_format_v1' as the bugs in read_line caused the queries to be read a little funny and we want to preserve the result file format(at this time) mysql-test/r/mysqltest.result: Update result file --- client/mysqltest.c | 205 ++++++++++++++++++++++++---------- mysql-test/r/mysqltest.result | 4 +- 2 files changed, 147 insertions(+), 62 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 2b0fcb0faa4..2c00c4b339a 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1530,7 +1530,7 @@ void do_system(struct st_query *command) SYNOPSIS do_echo() - q called command + command called command DESCRIPTION echo text @@ -1549,14 +1549,12 @@ void do_system(struct st_query *command) int do_echo(struct st_query *command) { - DYNAMIC_STRING *ds, ds_echo; - - ds= &ds_res; + DYNAMIC_STRING ds_echo; init_dynamic_string(&ds_echo, "", command->query_len, 256); do_eval(&ds_echo, command->first_argument, FALSE); - dynstr_append_mem(ds, ds_echo.str, ds_echo.length); - dynstr_append_mem(ds, "\n", 1); + dynstr_append_mem(&ds_res, ds_echo.str, ds_echo.length); + dynstr_append_mem(&ds_res, "\n", 1); dynstr_free(&ds_echo); command->last_argument= command->end; return(0); @@ -2901,9 +2899,7 @@ void do_block(enum block_cmd cmd, struct st_query* q) while (*p && my_isspace(charset_info, *p)) p++; - if (*p == '{') - die("Missing newline between %s and '{'", cmd_name); - if (*p) + if (*p && *p != '{') die("Missing '{' after %s. Found \"%s\"", cmd_name, p); var_init(&v,0,0,0,0); @@ -2971,6 +2967,27 @@ my_bool end_of_query(int c) } +void do_delimiter(struct st_query* command) +{ + char* p= command->first_argument; + DBUG_ENTER("do_delimiter"); + DBUG_PRINT("enter", ("first_argument: %s", command->first_argument)); + + while (*p && my_isspace(charset_info, *p)) + p++; + + if (!(*p)) + die("Can't set empty delimiter"); + + strmake(delimiter, p, sizeof(delimiter) - 1); + delimiter_length= strlen(delimiter); + + DBUG_PRINT("exit", ("delimiter: %s", delimiter)); + command->last_argument= p + delimiter_length; + DBUG_VOID_RETURN; +} + + /* Read one "line" from the file @@ -2997,19 +3014,19 @@ my_bool end_of_query(int c) int read_line(char *buf, int size) { - int c; - char quote; + char c, last_quote; char *p= buf, *buf_end= buf + size - 1; - int no_save= 0; - enum {R_NORMAL, R_Q, R_Q_IN_Q, R_SLASH_IN_Q, - R_COMMENT, R_LINE_START} state= R_LINE_START; + int skip_char= 0; + enum {R_NORMAL, R_Q, R_SLASH_IN_Q, + R_COMMENT, R_LINE_START} state= R_LINE_START; DBUG_ENTER("read_line"); - LINT_INIT(quote); + LINT_INIT(last_quote); start_lineno= cur_file->lineno; + DBUG_PRINT("info", ("start_lineno: %d", start_lineno)); for (; p < buf_end ;) { - no_save= 0; + skip_char= 0; c= my_getc(cur_file->file); if (feof(cur_file->file)) { @@ -3029,8 +3046,9 @@ int read_line(char *buf, int size) if (cur_block != block_stack) die("Missing end of block"); + *p= 0; DBUG_PRINT("info", ("end of file")); - DBUG_RETURN(1); + DBUG_RETURN(1); } cur_file--; start_lineno= cur_file->lineno; @@ -3044,61 +3062,74 @@ int read_line(char *buf, int size) /* Convert cr/lf to lf */ if (p != buf && *(p-1) == '\r') - *(p-1)= 0; + p--; } switch(state) { case R_NORMAL: - /* Only accept '{' in the beginning of a line */ if (end_of_query(c)) { *p= 0; + DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_RETURN(0); + } + else if ((c == '{' && + (!strncasecmp(buf, "while", min(5, p - buf)) || + !strncasecmp(buf, "if", min(2, p - buf))))) + { + /* Only if and while commands can be terminated by { */ + *p++= c; + *p= 0; + DBUG_PRINT("exit", ("Found '{' indicating begining of block")); DBUG_RETURN(0); } else if (c == '\'' || c == '"' || c == '`') { - quote= c; + last_quote= c; state= R_Q; } - else if (c == '\n') - { - state = R_LINE_START; - } break; + case R_COMMENT: if (c == '\n') { + /* Comments are terminated by newline */ *p= 0; + DBUG_PRINT("exit", ("Found newline in comment")); DBUG_RETURN(0); } break; + case R_LINE_START: - /* Only accept start of comment if this is the first line in query */ - if ((cur_file->lineno == start_lineno) && - (c == '#' || c == '-' || parsing_disabled)) + if (c == '#' || c == '-') { + /* A # or - in the first position of the line - this is a comment */ state = R_COMMENT; } else if (my_isspace(charset_info, c)) { + /* Skip all space at begining of line */ if (c == '\n') start_lineno= cur_file->lineno; /* Query hasn't started yet */ - no_save= 1; + skip_char= 1; + } + else if (end_of_query(c)) + { + *p= 0; + DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_RETURN(0); } else if (c == '}') { - *buf++= '}'; - *buf= 0; - DBUG_RETURN(0); - } - else if (end_of_query(c) || c == '{') - { + /* A "}" need to be by itself in the begining of a line to terminate */ + *p++= c; *p= 0; + DBUG_PRINT("exit", ("Found '}' in begining of a line")); DBUG_RETURN(0); } else if (c == '\'' || c == '"' || c == '`') { - quote= c; + last_quote= c; state= R_Q; } else @@ -3106,29 +3137,19 @@ int read_line(char *buf, int size) break; case R_Q: - if (c == quote) - state= R_Q_IN_Q; + if (c == last_quote) + state= R_NORMAL; else if (c == '\\') state= R_SLASH_IN_Q; break; - case R_Q_IN_Q: - if (end_of_query(c)) - { - *p= 0; - DBUG_RETURN(0); - } - if (c != quote) - state= R_NORMAL; - else - state= R_Q; - break; + case R_SLASH_IN_Q: state= R_Q; break; } - if (!no_save) + if (!skip_char) { /* Could be a multibyte character */ /* This code is based on the code in "sql_load.cc" */ @@ -3146,7 +3167,7 @@ int read_line(char *buf, int size) for (i= 1; i < charlen; i++) { if (feof(cur_file->file)) - goto found_eof; /* FIXME: could we just break here?! */ + goto found_eof; c= my_getc(cur_file->file); *p++ = c; } @@ -3163,10 +3184,64 @@ int read_line(char *buf, int size) *p++= c; } } - *p= 0; /* Always end with \0 */ - DBUG_RETURN(feof(cur_file->file)); + die("The input buffer is too small for this query.x\n" \ + "check your query or increase MAX_QUERY and recompile"); + DBUG_RETURN(0); } + +/* + Convert the read query to format version 1 + + That is: After newline, all spaces need to be skipped + unless the previous char was a quote + + This is due to an old bug that has now been fixed, but the + version 1 output format is preserved by using this function + +*/ + +static void convert_to_format_v1(char* query) +{ + int last_c_was_quote= 0; + char *p= query, *write= query; + char *end= strend(query); + char last_c; + + while (p <= end) + { + if (*p == '\n' && !last_c_was_quote) + { + *write++ = *p++; /* Save the newline */ + + /* Skip any spaces on next line */ + while (*p && my_isspace(charset_info, *p)) + p++; + + last_c_was_quote= 0; + } + else if (*p == '\'' || *p == '"' || *p == '`') + { + last_c= *p; + *write++ = *p++; + + /* Copy anything until the next quote of same type */ + while (*p && *p != last_c) + *write++ = *p++; + + *write++ = *p++; + + last_c_was_quote= 1; + } + else + { + *write++ = *p++; + last_c_was_quote= 0; + } + } +} + + /* Create a query from a set of lines @@ -3216,7 +3291,9 @@ int read_query(struct st_query** q_ptr) check_eol_junk(read_query_buf); DBUG_RETURN(1); } - + + convert_to_format_v1(read_query_buf); + DBUG_PRINT("info", ("query: %s", read_query_buf)); if (*p == '#') { @@ -3871,9 +3948,11 @@ static void fix_win_paths(const char* val, int len) } #endif + + /* Append the string to ds, with optional replace */ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, - const char *val, int len) + const char *val, int len) { #ifdef __WIN__ fix_win_paths(val, len); @@ -5032,7 +5111,7 @@ void get_query_type(struct st_query* q) } else if (q->type == Q_COMMENT_WITH_COMMAND && q->first_word_len && - q->query[q->first_word_len-1] == ';') + strcmp(q->query + q->first_word_len - 1, delimiter) == 0) { /* Detect comment with command using extra delimiter @@ -5142,7 +5221,7 @@ static void init_var_hash(MYSQL *mysql) test run completes */ -static void mark_progress(struct st_query* q, int line) +static void mark_progress(struct st_query* q __attribute__((unused)), int line) { char buf[32], *end; ulonglong timer= timer_now(); @@ -5332,9 +5411,7 @@ int main(int argc, char **argv) case Q_ECHO: do_echo(q); query_executed= 1; break; case Q_SYSTEM: do_system(q); break; case Q_DELIMITER: - strmake(delimiter, q->first_argument, sizeof(delimiter) - 1); - delimiter_length= strlen(delimiter); - q->last_argument= q->first_argument+delimiter_length; + do_delimiter(q); break; case Q_DISPLAY_VERTICAL_RESULTS: display_result_vertically= TRUE; @@ -5494,7 +5571,10 @@ int main(int argc, char **argv) break; } case Q_DISABLE_PARSING: - parsing_disabled++; + if (parsing_disabled == 0) + parsing_disabled++; + else + die("Parsing is already disabled"); break; case Q_ENABLE_PARSING: /* @@ -5503,6 +5583,8 @@ int main(int argc, char **argv) */ if (parsing_disabled > 0) parsing_disabled--; + else + die("Parsing is already enabled"); break; case Q_EXIT: @@ -5545,6 +5627,9 @@ int main(int argc, char **argv) start_lineno= 0; + if (parsing_disabled) + die("Test ended with parsing disabled"); + /* The whole test has been executed _sucessfully_. Time to compare result or save it to record file. diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index ef4dd83564b..4c2695e5caf 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -335,10 +335,10 @@ mysqltest: At line 1: missing ')' in while mysqltest: At line 1: Missing '{' after while. Found "dec $i" mysqltest: At line 1: Stray '}' - end of block before beginning mysqltest: At line 1: Stray 'end' command - end of block before beginning -mysqltest: At line 1: query '' failed: 1065: Query was empty +mysqltest: At line 1: query '{' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{' at line 1 mysqltest: At line 1: Missing '{' after while. Found "echo hej" mysqltest: At line 3: Missing end of block -mysqltest: At line 1: Missing newline between while and '{' +mysqltest: At line 3: Missing end of block mysqltest: At line 1: missing '(' in if mysqltest: At line 1: Stray 'end' command - end of block before beginning select "b" bs col1, "c" bs col2; From 61b52edd780d02679a4da7935c245074e007999d Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Jul 2006 18:00:08 +0200 Subject: [PATCH 011/235] Remove todo about better manual client/mysqltest.c: Remove the TODO saying we need better manual since that has been fixed now. --- client/mysqltest.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 2c00c4b339a..3afbf19ed7c 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -15,8 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* mysqltest test tool - * See the manual for more information - * TODO: document better how mysqltest works + * See the "MySQL Test framework manual" for more information * * Written by: * Sasha Pachev From cafd2566255e11910b9bb49c2978450b2ca0ef75 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Jul 2006 18:01:42 +0200 Subject: [PATCH 012/235] Remove outdated TODO list --- client/mysqltest.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3afbf19ed7c..4100267fa08 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -24,23 +24,6 @@ * Jani **/ -/********************************************************************** - TODO: - -- Do comparison line by line, instead of doing a full comparison of - the text file. This will save space as we don't need to keep many - results in memory. It will also make it possible to do simple - 'comparison' fixes like accepting the result even if a float differed - in the last decimals. - -- Don't buffer lines from the test that you don't expect to need - again. - -- Change 'read_line' to be faster by using the readline.cc code; - We can do better than calling feof() for each character! - -**********************************************************************/ - #define MTEST_VERSION "2.6" #include From 1c0baed86c08917d8cd6171b9fdb73ec3b6a1d62 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Jul 2006 18:21:31 +0200 Subject: [PATCH 013/235] Cleanup error messages in mysqltest client/mysqltest.c: Cleanup error messages, no need to supply line number in calls to 'die' that is done automatically if needed. Set start_lineno to 0 as default. --- client/mysqltest.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 4100267fa08..c3db4cf9659 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -162,7 +162,7 @@ typedef struct static test_file file_stack[MAX_INCLUDE_DEPTH]; static test_file* cur_file; static test_file* file_stack_end; -uint start_lineno; /* Start line of query */ +static uint start_lineno= 0; /* Start line of query */ /* Stores regex substitutions */ @@ -997,8 +997,8 @@ int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused))) if (mysql_query(mysql,"show status like 'Slave_running'") || !(res=mysql_store_result(mysql))) - die("Query failed while probing slave for stop: %s", - mysql_error(mysql)); + die("Query failed while probing slave for stop: %d %s", + mysql_errno(mysql), mysql_error(mysql)); if (!(row=mysql_fetch_row(res)) || !row[1]) { mysql_free_result(res); @@ -1271,8 +1271,8 @@ int var_query_set(VAR* var, const char *query, const char** query_end) !(res = mysql_store_result(mysql))) { *end = 0; - die("Error running query '%s': %d: %s", query, - mysql_errno(mysql) ,mysql_error(mysql)); + die("Error running query '%s': %d %s", query, + mysql_errno(mysql), mysql_error(mysql)); } if ((row = mysql_fetch_row(res)) && row[0]) @@ -1563,7 +1563,7 @@ int do_sync_with_master2(long offset) wait_for_position: if (mysql_query(mysql, query_buf)) - die("failed in %s: %d: %s", query_buf, mysql_errno(mysql), + die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql), mysql_error(mysql)); if (!(res= mysql_store_result(mysql))) @@ -1629,13 +1629,12 @@ int do_save_master_pos() { ulong have_ndbcluster; if (mysql_query(mysql, query= "show variables like 'have_ndbcluster'")) - die("At line %u: failed in %s: %d: %s", start_lineno, query, + die("'%s' failed: %d %s", query, mysql_errno(mysql), mysql_error(mysql)); if (!(res= mysql_store_result(mysql))) - die("line %u: mysql_store_result() retuned NULL for '%s'", start_lineno, - query); + die("mysql_store_result() returned NULL for '%s'", query); if (!(row= mysql_fetch_row(res))) - die("line %u: empty result in %s", start_lineno, query); + die("Query '%s' returned empty result", query); have_ndbcluster= strcmp("YES", row[1]) == 0; mysql_free_result(res); @@ -1655,11 +1654,10 @@ int do_save_master_pos() if (count) sleep(1); if (mysql_query(mysql, query= "show engine ndb status")) - die("At line %u: failed in '%s': %d: %s", start_lineno, query, + die("failed in '%s': %d %s", query, mysql_errno(mysql), mysql_error(mysql)); if (!(res= mysql_store_result(mysql))) - die("line %u: mysql_store_result() retuned NULL for '%s'", - start_lineno, query); + die("mysql_store_result() returned NULL for '%s'", query); while ((row= mysql_fetch_row(res))) { if (strcmp(row[1], binlog) == 0) @@ -1677,8 +1675,8 @@ int do_save_master_pos() epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_trans_epoch, query); + die("result does not contain '%s' in '%s'", + latest_trans_epoch, query); } /* latest_applied_binlog_epoch */ while (*status && strncmp(status, latest_handled_binlog_epoch, @@ -1690,14 +1688,14 @@ int do_save_master_pos() tmp_epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_handled_binlog_epoch, query); + die("result does not contain '%s' in '%s'", + latest_handled_binlog_epoch, query); break; } } if (!row) - die("line %u: result does not contain '%s' in '%s'", - start_lineno, binlog, query); + die("result does not contain '%s' in '%s'", + binlog, query); count++; if (tmp_epoch >= epoch) do_continue= 0; @@ -1711,7 +1709,7 @@ int do_save_master_pos() } #endif if (mysql_query(mysql, query= "show master status")) - die("failed in show master status: %d: %s", + die("failed in 'show master status': %d %s", mysql_errno(mysql), mysql_error(mysql)); if (!(res = mysql_store_result(mysql))) From 1385320be8e7f9400da8ca9cf4473cc7cd317e37 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Jul 2006 19:16:51 +0200 Subject: [PATCH 014/235] Add new commands to mysqltest - to make it easier to write portable test scripts client/Makefile.am: Link mysqltest with mysys library client/mysqltest.c: Add new commands to mysqltest: - remove_file - copy_file - file_exists - write_file - perl mysql-test/r/mysqltest.result: Update result file mysql-test/t/mysqltest.test: Add tests for new commands --- client/Makefile.am | 3 +- client/mysqltest.c | 467 ++++++++++++++++++++++++++++++---- mysql-test/r/mysqltest.result | 11 + mysql-test/t/mysqltest.test | 75 ++++++ 4 files changed, 500 insertions(+), 56 deletions(-) diff --git a/client/Makefile.am b/client/Makefile.am index ff97243815a..94174614d30 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -46,7 +46,8 @@ mysqladmin_SOURCES = mysqladmin.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c \ $(yassl_dummy_link_fix) -mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) +mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) \ + $(top_builddir)/mysys/libmysys.a mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \ $(top_srcdir)/mysys/my_new.cc \ $(top_srcdir)/mysys/my_bit.c \ diff --git a/client/mysqltest.c b/client/mysqltest.c index c3db4cf9659..56c06a10f5b 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -24,7 +24,7 @@ * Jani **/ -#define MTEST_VERSION "2.6" +#define MTEST_VERSION "2.7" #include #include @@ -333,7 +333,8 @@ Q_EXIT, Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, Q_IF, Q_DISABLE_PARSING, Q_ENABLE_PARSING, -Q_REPLACE_REGEX, +Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, +Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -423,6 +424,11 @@ const char *command_names[]= "disable_parsing", "enable_parsing", "replace_regex", + "remove_file", + "file_exists", + "write_file", + "copy_file", + "perl", 0 }; @@ -468,7 +474,7 @@ static void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds, const char *from, int len); void free_pointer_array(POINTER_ARRAY *pa); static void do_eval(DYNAMIC_STRING *query_eval, const char *query, - my_bool pass_through_escape_chars); + const char* query_end, my_bool pass_through_escape_chars); static void str_to_file(const char *fname, char *str, int size); #ifdef __WIN__ @@ -501,8 +507,8 @@ static void handle_error(const char *query, struct st_query *q, const char *err_sqlstate, DYNAMIC_STRING *ds); static void handle_no_error(struct st_query *q); -static void do_eval(DYNAMIC_STRING* query_eval, const char *query, - my_bool pass_through_escape_chars) +static void do_eval(DYNAMIC_STRING *query_eval, const char *query, + const char *query_end, my_bool pass_through_escape_chars) { const char *p; register char c, next_c; @@ -510,7 +516,7 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query, VAR* v; DBUG_ENTER("do_eval"); - for (p= query; (c = *p); ++p) + for (p= query; (c = *p) && p < query_end; ++p) { switch(c) { case '$': @@ -533,9 +539,9 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query, escaped = 0; dynstr_append_mem(query_eval, p, 1); } - else if (next_c == '\\' || next_c == '$') + else if (next_c == '\\' || next_c == '$' || next_c == '"') { - /* Set escaped only if next char is \ or $ */ + /* Set escaped only if next char is \, " or $ */ escaped = 1; if (pass_through_escape_chars) @@ -556,6 +562,108 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query, } +enum arg_type +{ + ARG_STRING, + ARG_REST +}; + +struct command_arg { + const char* argname; /* Name of argument */ + enum arg_type type; /* Type of argument */ + my_bool required; /* Argument required */ + DYNAMIC_STRING *ds; /* Storage for string argument */ + const char *description; /* Description of the argument */ +}; + +static void check_command_args(struct st_query *command, const char *arguments, + const struct command_arg *args, int num_args) +{ + int i; + const char *ptr= arguments; + const char *start; + + DBUG_ENTER("check_command_args"); + DBUG_PRINT("enter", ("num_args: %d", num_args)); + for (i= 0; i < num_args; i++) + { + const struct command_arg *arg= &args[i]; + + switch (arg->type) + { + /* A string surrounded by spaces */ + case ARG_STRING: + start= ptr; + /* Find end of arg */ + while (*ptr && !my_isspace(charset_info, *ptr)) + ptr++; + init_dynamic_string(arg->ds, 0, 256, 256); + do_eval(arg->ds, start, ptr, FALSE); + command->last_argument= (char*)ptr; + if (*ptr) + ptr++; + break; + + /* Rest of line */ + case ARG_REST: + start= ptr; + init_dynamic_string(arg->ds, 0, command->query_len, 256); + do_eval(arg->ds, start, command->end, FALSE); + command->last_argument= command->end; + break; + + default: + DBUG_ASSERT("Unknown argument type"); + break; + } + + /* Check required arg */ + if (arg->ds->length == 0 && arg->required) + die("Missing required argument '%s' to command '%.*s'", arg->argname, + command->first_word_len, command->query); + + } + DBUG_VOID_RETURN; +} + + +static void handle_command_error(struct st_query *command, uint error) +{ + DBUG_ENTER("handle_command_error"); + DBUG_PRINT("enter", ("error: %d", error)); + if (error != 0) + { + uint i; + + if (command->abort_on_error) + die("command \"%.*s\" failed", command->first_word_len, command->query); + for (i= 0; i < command->expected_errors; i++) + { + DBUG_PRINT("info", ("expected error: %d", + command->expected_errno[i].code.errnum)); + if ((command->expected_errno[i].type == ERR_ERRNO) && + (command->expected_errno[i].code.errnum == error)) + { + DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d", + command->first_word_len, command->query, error)); + DBUG_VOID_RETURN; + } + } + die("command \"%.*s\" failed with wrong error: %d", + command->first_word_len, command->query, error); + } + else if (command->expected_errno[0].type == ERR_ERRNO && + command->expected_errno[0].code.errnum != 0) + { + /* Error code we wanted was != 0, i.e. not an expected success */ + die("command \"%.*s\" succeeded - should have failed with errno %d...", + command->first_word_len, command->query, + command->expected_errno[0].code.errnum); + } + DBUG_VOID_RETURN; +} + + static void close_cons() { DBUG_ENTER("close_cons"); @@ -743,7 +851,7 @@ static int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) init_dynamic_string(&res_ds, "", stat_info.st_size+256, 256); if (eval_result) { - do_eval(&res_ds, tmp, FALSE); + do_eval(&res_ds, tmp, tmp + stat_info.st_size, FALSE); res_ptr= res_ds.str; res_len= res_ds.length; if (res_len != ds->length) @@ -1168,7 +1276,7 @@ static void do_exec(struct st_query *query) init_dynamic_string(&ds_cmd, 0, query->query_len+256, 256); /* Eval the command, thus replacing all environment variables */ - do_eval(&ds_cmd, cmd, TRUE); + do_eval(&ds_cmd, cmd, query->end, TRUE); cmd= ds_cmd.str; DBUG_PRINT("info", ("Executing '%s' as '%s'", @@ -1484,7 +1592,7 @@ void do_system(struct st_query *command) init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256); /* Eval the system command, thus replacing all environment variables */ - do_eval(&ds_cmd, command->first_argument, TRUE); + do_eval(&ds_cmd, command->first_argument, command->end, TRUE); DBUG_PRINT("info", ("running system command '%s' as '%s'", command->first_argument, ds_cmd.str)); @@ -1505,6 +1613,291 @@ void do_system(struct st_query *command) } +/* + SYNOPSIS + do_remove_file + command called command + + DESCRIPTION + remove_file + Remove the file +*/ + +static void do_remove_file(struct st_query *command) +{ + int error; + DYNAMIC_STRING ds_filename; + const struct command_arg rm_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to delete" + }; + DBUG_ENTER("do_remove_file"); + + check_command_args(command, command->first_argument, + rm_args, sizeof(rm_args)/sizeof(struct command_arg)); + + DBUG_PRINT("info", ("removing file: %s", ds_filename.str)); + error= my_delete(ds_filename.str, MYF(0)) != 0; + handle_command_error(command, error); + dynstr_free(&ds_filename); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_copy_file + command command handle + + DESCRIPTION + copy_file + Copy to + + NOTE! Will fail if exists +*/ + +static void do_copy_file(struct st_query *command) +{ + int error; + DYNAMIC_STRING ds_from_file; + DYNAMIC_STRING ds_to_file; + const struct command_arg copy_file_args[] = { + "from_file", ARG_STRING, TRUE, &ds_from_file, "Filename to copy from", + "to_file", ARG_STRING, TRUE, &ds_to_file, "Filename to copy to" + }; + DBUG_ENTER("do_copy_file"); + + check_command_args(command, command->first_argument, + copy_file_args, sizeof(copy_file_args)/sizeof(struct command_arg)); + + DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str)); + error= (my_copy(ds_from_file.str, ds_to_file.str, + MYF(MY_DONT_OVERWRITE_FILE)) != 0); + handle_command_error(command, error); + dynstr_free(&ds_from_file); + dynstr_free(&ds_to_file); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_file_exists + command called command + + DESCRIPTION + fiile_exist + Check if file exists +*/ + +static void do_file_exist(struct st_query *command) +{ + int error; + DYNAMIC_STRING ds_filename; + const struct command_arg file_exist_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist" + }; + DBUG_ENTER("do_file_exist"); + + check_command_args(command, command->first_argument, + file_exist_args, sizeof(file_exist_args)/sizeof(struct command_arg)); + + DBUG_PRINT("info", ("Checking for existence of file: %s", ds_filename.str)); + error= (access(ds_filename.str, F_OK) != 0); + handle_command_error(command, error); + dynstr_free(&ds_filename); + DBUG_VOID_RETURN; +} + + +/* + Read characters from line buffer or file. This is needed to allow + my_ungetc() to buffer MAX_DELIMITER characters for a file + + NOTE: + This works as long as one doesn't change files (with 'source file_name') + when there is things pushed into the buffer. This should however not + happen for any tests in the test suite. +*/ + +static int my_getc(FILE *file) +{ + if (line_buffer_pos == line_buffer) + return fgetc(file); + return *--line_buffer_pos; +} + + +static void my_ungetc(int c) +{ + *line_buffer_pos++= (char) c; +} + + +static my_bool match_delimiter(int c, const char* delim, uint length) +{ + uint i; + char tmp[MAX_DELIMITER]; + + if (c != *delim) + return 0; + + for (i= 1; i < length && + (c= my_getc(cur_file->file)) == *(delim + i); + i++) + tmp[i]= c; + + if (i == length) + return 1; /* Found delimiter */ + + /* didn't find delimiter, push back things that we read */ + my_ungetc(c); + while (i > 1) + my_ungetc(tmp[--i]); + return 0; +} + + +static void read_until_EOF(DYNAMIC_STRING* ds) +{ + int c; + DBUG_ENTER("read_until_EOF"); + + /* Read from file until delimiter EOF is found */ + while (1) + { + c= my_getc(cur_file->file); + + if (feof(cur_file->file)) + die("End of file encountered before 'EOF' delimiter was found"); + + if (match_delimiter(c, "EOF", 3)) + { + DBUG_PRINT("exit", ("Found EOF")); + break; + } + dynstr_append_mem(ds, (const char*)&c, 1); + } + DBUG_PRINT("exit", ("ds: %s", ds->str)); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_write_file + command called command + + DESCRIPTION + write_file ; + + <...> + < what to write line n> + EOF + + --write_file ; + + <...> + < what to write line n> + EOF + + Write everything between the "write_file" command and EOF to "file_name" + + NOTE! Overwrites existing file + +*/ + +static void do_write_file(struct st_query *command) +{ + DYNAMIC_STRING ds_content; + DYNAMIC_STRING ds_filename; + const struct command_arg write_file_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to write to", + }; + DBUG_ENTER("do_write_file"); + + check_command_args(command, + command->first_argument, + write_file_args, + sizeof(write_file_args)/sizeof(struct command_arg)); + + init_dynamic_string(&ds_content, "", 1024, 1024); + read_until_EOF(&ds_content); + DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str)); + str_to_file(ds_filename.str, ds_content.str, ds_content.length); + dynstr_free(&ds_content); + dynstr_free(&ds_filename); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_perl + command command handle + + DESCRIPTION + perl; + + <...> + + EOF + + Execute everything after "perl" until EOF as perl. + Useful for doing more advanced things + but still being able to execute it on all platforms. + + The function sets delimiter to EOF and remembers that this + is a perl command by setting "perl mode". The following lines + will then be parsed as any normal query, but when searching + for command in get_query_type, this function will be called + again since "perl mode" is on and the perl script can be + executed. +*/ + +static void do_perl(struct st_query *command) +{ + int error; + char buf[FN_REFLEN]; + FILE *res_file; + DYNAMIC_STRING ds_script; + DBUG_ENTER("do_perl"); + + init_dynamic_string(&ds_script, "", 1024, 1024); + read_until_EOF(&ds_script); + + DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); + + /* Format a name for a tmp .pl file that is unique for this process */ + my_snprintf(buf, sizeof(buf), "%s/tmp/tmp_%d.pl", + getenv("MYSQLTEST_VARDIR"), getpid()); + str_to_file(buf, ds_script.str, ds_script.length); + + /* Format the perl command */ + my_snprintf(buf, sizeof(buf), "perl %s/tmp/tmp_%d.pl", + getenv("MYSQLTEST_VARDIR"), getpid()); + + if (!(res_file= popen(buf, "r")) && command->abort_on_error) + die("popen(\"%s\", \"r\") failed", buf); + + while (fgets(buf, sizeof(buf), res_file)) + { + if (disable_result_log) + { + buf[strlen(buf)-1]=0; + DBUG_PRINT("exec_result",("%s", buf)); + } + else + { + replace_dynstr_append(&ds_res, buf); + } + } + error= pclose(res_file); + handle_command_error(command, WEXITSTATUS(error)); + dynstr_free(&ds_script); + DBUG_VOID_RETURN; +} + + /* Print the content between echo and to result file. Evaluate all variables in the string before printing, allow @@ -1534,7 +1927,7 @@ int do_echo(struct st_query *command) DYNAMIC_STRING ds_echo; init_dynamic_string(&ds_echo, "", command->query_len, 256); - do_eval(&ds_echo, command->first_argument, FALSE); + do_eval(&ds_echo, command->first_argument, command->end, FALSE); dynstr_append_mem(&ds_res, ds_echo.str, ds_echo.length); dynstr_append_mem(&ds_res, "\n", 1); dynstr_free(&ds_echo); @@ -2900,50 +3293,9 @@ void do_block(enum block_cmd cmd, struct st_query* q) } -/* - Read characters from line buffer or file. This is needed to allow - my_ungetc() to buffer MAX_DELIMITER characters for a file - - NOTE: - This works as long as one doesn't change files (with 'source file_name') - when there is things pushed into the buffer. This should however not - happen for any tests in the test suite. -*/ - -int my_getc(FILE *file) -{ - if (line_buffer_pos == line_buffer) - return fgetc(file); - return *--line_buffer_pos; -} - -void my_ungetc(int c) -{ - *line_buffer_pos++= (char) c; -} - - my_bool end_of_query(int c) { - uint i; - char tmp[MAX_DELIMITER]; - - if (c != *delimiter) - return 0; - - for (i= 1; i < delimiter_length && - (c= my_getc(cur_file->file)) == *(delimiter + i); - i++) - tmp[i]= c; - - if (i == delimiter_length) - return 1; /* Found delimiter */ - - /* didn't find delimiter, push back things that we read */ - my_ungetc(c); - while (i > 1) - my_ungetc(tmp[--i]); - return 0; + return match_delimiter(c, delimiter, delimiter_length); } @@ -4786,7 +5138,7 @@ static void run_query(MYSQL *mysql, struct st_query *command, int flags) if (command->type == Q_EVAL) { init_dynamic_string(&eval_query, "", command->query_len+256, 1024); - do_eval(&eval_query, command->query, FALSE); + do_eval(&eval_query, command->query, command->end, FALSE); query = eval_query.str; query_len = eval_query.length; } @@ -5390,6 +5742,11 @@ int main(int argc, char **argv) case Q_DEC: do_modify_var(q, DO_DEC); break; case Q_ECHO: do_echo(q); query_executed= 1; break; case Q_SYSTEM: do_system(q); break; + case Q_REMOVE_FILE: do_remove_file(q); break; + case Q_FILE_EXIST: do_file_exist(q); break; + case Q_WRITE_FILE: do_write_file(q); break; + case Q_COPY_FILE: do_copy_file(q); break; + case Q_PERL: do_perl(q); break; case Q_DELIMITER: do_delimiter(q); break; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 4c2695e5caf..fdc43e8852b 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -467,3 +467,14 @@ a D 1 1 1 4 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 +mysqltest: At line 1: End of line junk detected: "write_file filename "; +" +mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists' +mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file' +mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' +hello +hello +hello diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 86cfd66ae2b..8aa85937c17 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1159,3 +1159,78 @@ insert into t1 values (2,4); --replace_regex /A/C/ /B/D/i /3/2/ /2/1/ select * from t1; drop table t1; + +# ---------------------------------------------------------------------------- +# test for remove_file +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "remove_file ;" | $MYSQL_TEST 2>&1 + +--error 1 +remove_file non_existing_file; + +# ---------------------------------------------------------------------------- +# test for write_file +# ---------------------------------------------------------------------------- +--error 1 +--exec echo "write_file ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "write_file filename ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "write_file filename \";" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# test for file_exist +# ---------------------------------------------------------------------------- +--error 1 +--exec echo "file_exists ;" | $MYSQL_TEST 2>&1 + +--error 0,1 +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +--error 1 +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +Content for test_file1 +EOF +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +--error 1 +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + + +# ---------------------------------------------------------------------------- +# test for copy_file +# ---------------------------------------------------------------------------- +--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +file1 +EOF + +copy_file $MYSQLTEST_VARDIR/tmp/file1.tmp $MYSQLTEST_VARDIR/tmp/file2.tmp; +file_exists $MYSQLTEST_VARDIR/tmp/file2.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; + +--error 1 +--exec echo "copy_file ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "copy_file from_file;" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# test for perl +# ---------------------------------------------------------------------------- +--perl +print "hello\n"; +EOF + +perl; +print "hello\n"; +EOF + +perl; + # Print "hello" + print "hello\n"; +EOF From 59601768338b0ef997be3bb06278f34b1c577415 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 30 Jul 2006 19:46:04 +0200 Subject: [PATCH 015/235] remove unneeded bugfix when read_line function in mysqltest has been fixed client/mysqltest.c: Remove the hack "q_send_flag" which seems to be a bug fix for a buggy 'read_line' function --- client/mysqltest.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 56c06a10f5b..13d5874628e 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -5588,7 +5588,7 @@ static void mark_progress(struct st_query* q __attribute__((unused)), int line) int main(int argc, char **argv) { struct st_query *q; - my_bool require_file=0, q_send_flag=0, abort_flag= 0, + my_bool require_file=0, abort_flag= 0, query_executed= 0; char save_file[FN_REFLEN]; MY_STAT res_info; @@ -5796,11 +5796,7 @@ int main(int argc, char **argv) int flags = QUERY_REAP; if (q->type != Q_REAP) /* for a full query, enable the send stage */ flags |= QUERY_SEND; - if (q_send_flag) - { - flags= QUERY_SEND; - q_send_flag=0; - } + if (save_file[0]) { strmov(q->record_file,save_file); @@ -5813,12 +5809,6 @@ int main(int argc, char **argv) break; } case Q_SEND: - if (!q->query[q->first_word_len]) - { - /* This happens when we use 'send' on its own line */ - q_send_flag=1; - break; - } /* fix up query pointer if this is first iteration for this line */ if (q->query == q->query_buf) q->query+= q->first_word_len; From 7f713ab402628ddbdf7a5024801d267b9ee7c078 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 7 Sep 2006 16:44:18 +0200 Subject: [PATCH 016/235] Bug#17039 Cursor with procedure crashes client - Change 'get_unit_column_type" to return the field list for the procedure sql/sql_union.cc: Change 'get_unit_column_type' to return the procedure field list if this is the execution of a procedure. tests/mysql_client_test.c: Add test case for using "procedure" in cursor. --- sql/sql_union.cc | 15 +++++++++++++-- tests/mysql_client_test.c | 14 ++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c5af81ae55a..b14acf26607 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -689,7 +689,17 @@ bool st_select_lex_unit::change_result(select_subselect *result, List *st_select_lex_unit::get_unit_column_types() { - bool is_union= test(first_select()->next_select()); + SELECT_LEX *sl= first_select(); + bool is_union= test(sl->next_select()); + bool is_procedure= test(sl->join->procedure); + + if (is_procedure) + { + /* Types for "SELECT * FROM t1 procedure analyse()" + are generated during execute */ + return &sl->join->procedure_fields_list; + } + if (is_union) { @@ -697,7 +707,8 @@ List *st_select_lex_unit::get_unit_column_types() /* Types are generated during prepare */ return &types; } - return &first_select()->item_list; + + return &sl->item_list; } bool st_select_lex::cleanup() diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 5ee63cb8738..15be89ca760 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11931,6 +11931,19 @@ static void test_cursors_with_union() fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); } + +static void test_cursors_with_procedure() +{ + const char *queries[]= + { + "SELECT * FROM t1 procedure analyse()" + }; + myheader("test_cursors_with_procedure"); + fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_ROW_BY_ROW_FETCH); + fetch_n(queries, sizeof(queries)/sizeof(*queries), USE_STORE_RESULT); +} + + /* Altough mysql_create_db(), mysql_rm_db() are deprecated since 4.0 they should not crash server and should not hang in case of errors. @@ -15297,6 +15310,7 @@ static struct my_tests_st my_tests[]= { { "test_view_insert_fields", test_view_insert_fields }, { "test_basic_cursors", test_basic_cursors }, { "test_cursors_with_union", test_cursors_with_union }, + { "test_cursors_with_procedure", test_cursors_with_procedure }, { "test_truncation", test_truncation }, { "test_truncation_option", test_truncation_option }, { "test_client_character_set", test_client_character_set }, From da5e2660b7ecea8b255f8b7e4f69c61d157918d7 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Sep 2006 21:06:14 -0600 Subject: [PATCH 017/235] Bug #4053: too many of "error 1236: 'binlog truncated in the middle of event' from master" - Detect read failure in my_read_charset_file mysys/charset.c: Use my_read instead of read(), and detect read failure, in my_read_charset_file() --- mysys/charset.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/mysys/charset.c b/mysys/charset.c index 665f2efecd8..6f2d4d3c347 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -312,7 +312,7 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) { char *buf; int fd; - uint len; + uint len, tmp_len; MY_STAT stat_info; if (!my_stat(filename, &stat_info, MYF(myflags)) || @@ -321,12 +321,11 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) return TRUE; if ((fd=my_open(filename,O_RDONLY,myflags)) < 0) - { - my_free(buf,myflags); - return TRUE; - } - len=read(fd,buf,len); + goto error; + tmp_len=my_read(fd, buf, len, myflags); my_close(fd,myflags); + if (tmp_len != len) + goto error; if (my_parse_charset_xml(buf,len,add_collation)) { @@ -340,6 +339,10 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) my_free(buf, myflags); return FALSE; + +error: + my_free(buf, myflags); + return TRUE; } From d7a1f97c15fc5adaaf3116b8fb9ee32783498165 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Sep 2006 23:19:24 -0600 Subject: [PATCH 018/235] Bug #4053: too many of "error 1236: 'binlog truncated in the middle of event' from master" - Fix my_read/my_write to handle return values from read/write correctly - Add debugging 'deprecated function' warning to my_lread/my_lwrite - Add debugging 'error, read/write interrupt not handled' warning to my_quick_read/my_quick_write There is no test case associated with these changes. However, this is a conservative change, and no repeatable test case is available. mysys/my_lread.c: Warn about using deprecated function. mysys/my_lwrite.c: Warn about using deprecated function. mysys/my_pread.c: Handle interrupted read() or write() (EINTR) properly mysys/my_quick.c: Warn about interrupted read() or write(), which is not handled by my_quick_read() or my_quick_write(). mysys/my_read.c: Handle interrupted read() (EINTR) properly mysys/my_write.c: Handle interrupted write() (EINTR) properly --- mysys/my_lread.c | 2 ++ mysys/my_lwrite.c | 2 ++ mysys/my_pread.c | 12 ++++++++---- mysys/my_quick.c | 26 +++++++++++++++++++++++++- mysys/my_read.c | 8 ++++++-- mysys/my_write.c | 20 +++++++++++++------- 6 files changed, 56 insertions(+), 14 deletions(-) diff --git a/mysys/my_lread.c b/mysys/my_lread.c index 601d772b844..a96febe4474 100644 --- a/mysys/my_lread.c +++ b/mysys/my_lread.c @@ -30,6 +30,8 @@ uint32 my_lread(int Filedes, byte *Buffer, uint32 Count, myf MyFlags) DBUG_PRINT("my",("Fd: %d Buffer: %ld Count: %ld MyFlags: %d", Filedes, Buffer, Count, MyFlags)); + DBUG_PRINT("error", ("Deprecated my_lread() function should not be used.")); + /* Temp hack to get count to int32 while read wants int */ if ((readbytes = (uint32) read(Filedes, Buffer, (uint) Count)) != Count) { diff --git a/mysys/my_lwrite.c b/mysys/my_lwrite.c index e1a3decd053..cfdbd5d4576 100644 --- a/mysys/my_lwrite.c +++ b/mysys/my_lwrite.c @@ -26,6 +26,8 @@ uint32 my_lwrite(int Filedes, const byte *Buffer, uint32 Count, myf MyFlags) DBUG_PRINT("my",("Fd: %d Buffer: %lx Count: %ld MyFlags: %d", Filedes, Buffer, Count, MyFlags)); + DBUG_PRINT("error", ("Deprecated my_lwrite() function should not be used.")); + /* Temp hack to get count to int32 while write wants int */ if ((writenbytes = (uint32) write(Filedes, Buffer, (uint) Count)) != Count) { diff --git a/mysys/my_pread.c b/mysys/my_pread.c index f76233fc4cc..70990ad12a6 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -52,8 +52,12 @@ uint my_pread(File Filedes, byte *Buffer, uint Count, my_off_t offset, DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d", readbytes,Count,Filedes,my_errno)); #ifdef THREAD - if (readbytes == 0 && errno == EINTR) - continue; /* Interrupted */ + if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR) + { + DBUG_PRINT("debug", ("my_pread() was interrupted and returned %d", + (int) readbytes)); + continue; /* Interrupted */ + } #endif if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { @@ -124,8 +128,8 @@ uint my_pwrite(int Filedes, const byte *Buffer, uint Count, my_off_t offset, VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC)); continue; } - if ((writenbytes == 0 && my_errno == EINTR) || - (writenbytes > 0 && (uint) writenbytes != (uint) -1)) + if ((writenbytes > 0 && (uint) writenbytes != (uint) -1) || + my_errno == EINTR) continue; /* Retry */ #endif if (MyFlags & (MY_NABP | MY_FNABP)) diff --git a/mysys/my_quick.c b/mysys/my_quick.c index 44ed3fc0b2c..ffc8160c371 100644 --- a/mysys/my_quick.c +++ b/mysys/my_quick.c @@ -26,6 +26,14 @@ uint my_quick_read(File Filedes,byte *Buffer,uint Count,myf MyFlags) if ((readbytes = (uint) read(Filedes, Buffer, Count)) != Count) { +#ifndef DBUG_OFF + if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR) + { + DBUG_PRINT("error", ("my_quick_read() was interrupted and returned %d" + ". This function does not retry the read!", + (int) readbytes)); + } +#endif my_errno=errno; return readbytes; } @@ -35,8 +43,24 @@ uint my_quick_read(File Filedes,byte *Buffer,uint Count,myf MyFlags) uint my_quick_write(File Filedes,const byte *Buffer,uint Count) { - if ((uint) write(Filedes,Buffer,Count) != Count) +#ifndef DBUG_OFF + uint writtenbytes; +#endif + + if (( +#ifndef DBUG_OFF + writtenbytes = +#endif + (uint) write(Filedes,Buffer,Count)) != Count) { +#ifndef DBUG_OFF + if ((writtenbytes == 0 || (int) writtenbytes == -1) && errno == EINTR) + { + DBUG_PRINT("error", ("my_quick_write() was interrupted and returned %d" + ". This function does not retry the write!", + (int) writtenbytes)); + } +#endif my_errno=errno; return (uint) -1; } diff --git a/mysys/my_read.c b/mysys/my_read.c index b7621ac99eb..b59ada20977 100644 --- a/mysys/my_read.c +++ b/mysys/my_read.c @@ -51,8 +51,12 @@ uint my_read(File Filedes, byte *Buffer, uint Count, myf MyFlags) DBUG_PRINT("warning",("Read only %ld bytes off %ld from %d, errno: %d", readbytes,Count,Filedes,my_errno)); #ifdef THREAD - if (readbytes == 0 && errno == EINTR) - continue; /* Interrupted */ + if ((readbytes == 0 || (int) readbytes == -1) && errno == EINTR) + { + DBUG_PRINT("debug", ("my_read() was interrupted and returned %d", + (int) readbytes)); + continue; /* Interrupted */ + } #endif if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) { diff --git a/mysys/my_write.c b/mysys/my_write.c index 1d1a893090a..de762c16a07 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -57,18 +57,24 @@ uint my_write(int Filedes, const byte *Buffer, uint Count, myf MyFlags) VOID(sleep(MY_WAIT_FOR_USER_TO_FIX_PANIC)); continue; } - if (!writenbytes) + + if ((writenbytes == 0 || (int) writenbytes == -1)) { - /* We may come here on an interrupt or if the file quote is exeeded */ if (my_errno == EINTR) - continue; - if (!errors++) /* Retry once */ { - errno=EFBIG; /* Assume this is the error */ - continue; + DBUG_PRINT("debug", ("my_write() was interrupted and returned %d", + (int) writenbytes)); + continue; /* Interrupted */ + } + + if (!writenbytes && !errors++) /* Retry once */ + { + /* We may come here if the file quota is exeeded */ + errno=EFBIG; /* Assume this is the error */ + continue; } } - else if ((uint) writenbytes != (uint) -1) + else continue; /* Retry */ #endif if (MyFlags & (MY_NABP | MY_FNABP)) From fcc19af8aad224c3d02319ce4f74f450d781fd9a Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 14 Sep 2006 23:29:44 -0600 Subject: [PATCH 019/235] Remove unused (and incorrect) my_lread() and my_lwrite() BitKeeper/deleted/.del-my_lwrite.c: Delete: mysys/my_lwrite.c BitKeeper/deleted/.del-my_lread.c: Delete: mysys/my_lread.c --- mysys/CMakeLists.txt | 2 +- mysys/Makefile.am | 2 +- mysys/make-ccc | 2 +- mysys/my_lread.c | 55 -------------------------------------------- mysys/my_lwrite.c | 48 -------------------------------------- 5 files changed, 3 insertions(+), 106 deletions(-) delete mode 100644 mysys/my_lread.c delete mode 100644 mysys/my_lwrite.c diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt index 4aa99a70121..7b362b4c1f9 100644 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -20,7 +20,7 @@ ADD_LIBRARY(mysys array.c charset-def.c charset.c checksum.c default.c default_m my_clock.c my_compress.c my_conio.c my_copy.c my_crc32.c my_create.c my_delete.c my_div.c my_error.c my_file.c my_fopen.c my_fstream.c my_gethostbyname.c my_gethwaddr.c my_getopt.c my_getsystime.c my_getwd.c my_handler.c my_init.c - my_lib.c my_lock.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c + my_lib.c my_lock.c my_lockmem.c my_malloc.c my_messnc.c my_mkdir.c my_mmap.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_sleep.c my_static.c my_symlink.c my_symlink2.c my_sync.c my_thr_init.c my_wincond.c diff --git a/mysys/Makefile.am b/mysys/Makefile.am index b209d64e78f..79d79d41c34 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -43,7 +43,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ tree.c trie.c list.c hash.c array.c string.c typelib.c \ my_copy.c my_append.c my_lib.c \ my_delete.c my_rename.c my_redel.c \ - my_chsize.c my_lread.c my_lwrite.c my_clock.c \ + my_chsize.c my_clock.c \ my_quick.c my_lockmem.c my_static.c \ my_sync.c my_getopt.c my_mkdir.c \ default_modify.c default.c \ diff --git a/mysys/make-ccc b/mysys/make-ccc index 9c54185682a..b34bd80e1d1 100755 --- a/mysys/make-ccc +++ b/mysys/make-ccc @@ -1,4 +1,4 @@ rm -f .deps/* raid.o mf_iocache.o libmysys.a -ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_lread.c my_lwrite.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c +ccc -DDEFAULT_BASEDIR="\"/usr/local/mysql\"" -DDATADIR="\"/usr/local/mysql/var\"" -DHAVE_CONFIG_H -I./../include -I../include -I.. -DDBUG_OFF -fast -O3 -fomit-frame-pointer -c array.c checksum.c default.c errors.c getopt.c getopt1.c getvar.c hash.c list.c mf_brkhant.c mf_cache.c mf_casecnv.c mf_dirname.c mf_fn_ext.c mf_format.c mf_getdate.c mf_keycache.c mf_loadpath.c mf_pack.c mf_pack2.c mf_path.c mf_qsort.c mf_qsort2.c mf_radix.c mf_reccache.c mf_same.c mf_sort.c mf_soundex.c mf_stripp.c mf_unixpath.c mf_wcomp.c mf_wfile.c mulalloc.c my_alarm.c my_alloc.c my_append.c my_chsize.c my_clock.c my_compress.c my_copy.c my_create.c my_delete.c my_div.c my_error.c my_fopen.c my_fstream.c my_getwd.c my_init.c my_lib.c my_lockmem.c my_malloc.c my_messnc.c my_mkdir.c my_net.c my_once.c my_open.c my_pread.c my_pthread.c my_quick.c my_read.c my_realloc.c my_redel.c my_rename.c my_seek.c my_static.c my_tempnam.c my_thr_init.c my_write.c ptr_cmp.c queues.c safemalloc.c string.c thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c tree.c typelib.c make raid.o mf_iocache.o my_lock.o ar -cr libmysys.a array.o raid.o mf_iocache.o my_lock.o diff --git a/mysys/my_lread.c b/mysys/my_lread.c deleted file mode 100644 index a96febe4474..00000000000 --- a/mysys/my_lread.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "mysys_priv.h" -#include "mysys_err.h" - - /* Read a chunk of bytes from a file */ - -uint32 my_lread(int Filedes, byte *Buffer, uint32 Count, myf MyFlags) - /* File descriptor */ - /* Buffer must be at least count bytes */ - /* Max number of bytes returnd */ - /* Flags on what to do on error */ -{ - uint32 readbytes; - DBUG_ENTER("my_lread"); - DBUG_PRINT("my",("Fd: %d Buffer: %ld Count: %ld MyFlags: %d", - Filedes, Buffer, Count, MyFlags)); - - DBUG_PRINT("error", ("Deprecated my_lread() function should not be used.")); - - /* Temp hack to get count to int32 while read wants int */ - if ((readbytes = (uint32) read(Filedes, Buffer, (uint) Count)) != Count) - { - my_errno=errno; - if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) - { - if (readbytes == MY_FILE_ERROR) - my_error(EE_READ, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),errno); - else - if (MyFlags & (MY_NABP | MY_FNABP)) - my_error(EE_EOFERR, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),errno); - } - if (readbytes == MY_FILE_ERROR || MyFlags & (MY_NABP | MY_FNABP)) - DBUG_RETURN((uint32) -1); /* Return med felkod */ - } - if (MyFlags & (MY_NABP | MY_FNABP)) - DBUG_RETURN(0); /* Ok vid l{sning */ - DBUG_RETURN(readbytes); -} /* my_lread */ diff --git a/mysys/my_lwrite.c b/mysys/my_lwrite.c deleted file mode 100644 index 02c56a69ba4..00000000000 --- a/mysys/my_lwrite.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2000 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include "mysys_priv.h" -#include "mysys_err.h" - - /* Write a chunk of bytes to a file */ - -uint32 my_lwrite(int Filedes, const byte *Buffer, uint32 Count, myf MyFlags) -{ - uint32 writenbytes; - DBUG_ENTER("my_lwrite"); - DBUG_PRINT("my",("Fd: %d Buffer: 0x%lx Count: %ld MyFlags: %d", - Filedes, Buffer, Count, MyFlags)); - - DBUG_PRINT("error", ("Deprecated my_lwrite() function should not be used.")); - - /* Temp hack to get count to int32 while write wants int */ - if ((writenbytes = (uint32) write(Filedes, Buffer, (uint) Count)) != Count) - { - my_errno=errno; - if (writenbytes == (uint32) -1 || MyFlags & (MY_NABP | MY_FNABP)) - { - if (MyFlags & (MY_WME | MY_FAE | MY_FNABP)) - { - my_error(EE_WRITE, MYF(ME_BELL+ME_WAITTANG), - my_filename(Filedes),errno); - } - DBUG_RETURN((uint32) -1); /* Return med felkod */ - } - } - if (MyFlags & (MY_NABP | MY_FNABP)) - DBUG_RETURN(0); /* Ok vid l{sning */ - DBUG_RETURN(writenbytes); -} /* my_lwrite */ From e8cc98c87a6036311099d1a7ea60855556e3665a Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Sep 2006 11:22:01 +0200 Subject: [PATCH 020/235] Bug#21811 Odd casting with date + INTERVAL arithmetic - The definition of the result type of a type_date function didn't include INTERVAL_WEEK - This patch adds an explicit test for INTERVAL_WEEK which results in the result type for an item_date_add_intervall operation being DATE rather than DATETIME when one parameter is INTERVAL_WEEK. sql/item_timefunc.cc: Added explicit test for INTERVAL_WEEK to evaluate as MYSQL_TYPE_DATE --- sql/item_timefunc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index febc92e34f6..3886af27158 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1876,7 +1876,7 @@ void Item_date_add_interval::fix_length_and_dec() cached_field_type= MYSQL_TYPE_DATETIME; else if (arg0_field_type == MYSQL_TYPE_DATE) { - if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH) + if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH || int_type == INTERVAL_WEEK ) cached_field_type= arg0_field_type; else cached_field_type= MYSQL_TYPE_DATETIME; From c84223043b9674b3c670c12be7ffd97a95cd8512 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 22 Sep 2006 20:58:16 +0200 Subject: [PATCH 021/235] Immediately skip tests that need innodb if mysqld does not support it mysql-test/lib/mtr_cases.pl: immediately skip tests that need innodb if mysqld does not support it mysql-test/mysql-test-run.pl: Check if innodb is supported --- mysql-test/lib/mtr_cases.pl | 7 +++++++ mysql-test/mysql-test-run.pl | 22 ++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index cfd07abb9e0..09f28682345 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -503,6 +503,13 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'skip'}= 1; $tinfo->{'comment'}= "Test need debug binaries"; } + + if ( $tinfo->{'innodb_test'} && ! $::glob_innodb_supported ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test need innodb"; + } + } # We can't restart a running server that may be in use diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 9f1ce3b9b01..00f87af01f1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -333,6 +333,7 @@ our @data_dir_lst; our $used_binlog_format; our $debug_compiled_binaries; our $glob_tot_real_time= 0; +our $glob_innodb_supported; ###################################################################### # @@ -351,6 +352,7 @@ sub cleanup_stale_files (); sub check_ssl_support (); sub check_running_as_root(); sub check_ndbcluster_support (); +sub check_innodb_support (); sub rm_ndbcluster_tables ($); sub ndbcluster_start_install ($); sub ndbcluster_start ($$); @@ -391,6 +393,7 @@ sub main () { executable_setup(); check_ndbcluster_support(); + check_innodb_support(); check_ssl_support(); check_debug_support(); @@ -1832,6 +1835,25 @@ sub check_debug_support () { $debug_compiled_binaries= 1; } +sub check_innodb_support () { + + # check innodb support by testing using a switch + # that is only available in that case + if ( mtr_run($exe_mysqld, + ["--no-defaults", + "--innodb-data-file-path", + "--help"], + "", "/dev/null", "/dev/null", "") != 0 ) + { + # mtr_report("Binaries does not support innodb"); + $glob_innodb_supported= 0; + + return; + } + mtr_report("Using innodb when necessary"); + $glob_innodb_supported= 1; +} + ############################################################################## # # Start the ndb cluster From 8152207223adaabb7fe9e402ee27e3d5beaa0272 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 25 Sep 2006 16:44:15 +0200 Subject: [PATCH 022/235] Bug#21868 Server crashes if encrypted certificate key provided - Add test case which runs the same tests as ssl.test but with a different DES encrypted key mysql-test/std_data/server-key-des.pem: BitKeeper file /home/msvensson/mysql/bug21868/my50-bug21868/mysql-test/std_data/server-key-des.pem mysql-test/std_data/server-cert-des.pem: BitKeeper file /home/msvensson/mysql/bug21868/my50-bug21868/mysql-test/std_data/server-cert-des.pem mysql-test/r/ssl_des.result: New BitKeeper file ``mysql-test/r/ssl_des.result'' mysql-test/t/ssl_des-master.opt: New BitKeeper file ``mysql-test/t/ssl_des-master.opt'' mysql-test/t/ssl_des.test: New BitKeeper file ``mysql-test/t/ssl_des.test'' --- mysql-test/r/ssl_des.result | 2159 +++++++++++++++++++++++ mysql-test/std_data/server-cert-des.pem | 16 + mysql-test/std_data/server-key-des.pem | 18 + mysql-test/t/ssl_des-master.opt | 1 + mysql-test/t/ssl_des.test | 19 + 5 files changed, 2213 insertions(+) create mode 100644 mysql-test/r/ssl_des.result create mode 100644 mysql-test/std_data/server-cert-des.pem create mode 100644 mysql-test/std_data/server-key-des.pem create mode 100644 mysql-test/t/ssl_des-master.opt create mode 100644 mysql-test/t/ssl_des.test diff --git a/mysql-test/r/ssl_des.result b/mysql-test/r/ssl_des.result new file mode 100644 index 00000000000..cd8bf52139e --- /dev/null +++ b/mysql-test/r/ssl_des.result @@ -0,0 +1,2159 @@ +SHOW STATUS LIKE 'Ssl_cipher'; +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA +drop table if exists t1,t2,t3,t4; +CREATE TABLE t1 ( +Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, +Varor_period smallint(4) unsigned DEFAULT '0' NOT NULL +); +INSERT INTO t1 VALUES (9410,9412); +select period from t1; +period +9410 +select * from t1; +Period Varor_period +9410 9412 +select t1.* from t1; +Period Varor_period +9410 9412 +CREATE TABLE t2 ( +auto int not null auto_increment, +fld1 int(6) unsigned zerofill DEFAULT '000000' NOT NULL, +companynr tinyint(2) unsigned zerofill DEFAULT '00' NOT NULL, +fld3 char(30) DEFAULT '' NOT NULL, +fld4 char(35) DEFAULT '' NOT NULL, +fld5 char(35) DEFAULT '' NOT NULL, +fld6 char(4) DEFAULT '' NOT NULL, +UNIQUE fld1 (fld1), +KEY fld3 (fld3), +PRIMARY KEY (auto) +); +select t2.fld3 from t2 where companynr = 58 and fld3 like "%imaginable%"; +fld3 +imaginable +select fld3 from t2 where fld3 like "%cultivation" ; +fld3 +cultivation +select t2.fld3,companynr from t2 where companynr = 57+1 order by fld3; +fld3 companynr +concoct 58 +druggists 58 +engrossing 58 +Eurydice 58 +exclaimers 58 +ferociousness 58 +hopelessness 58 +Huey 58 +imaginable 58 +judges 58 +merging 58 +ostrich 58 +peering 58 +Phelps 58 +presumes 58 +Ruth 58 +sentences 58 +Shylock 58 +straggled 58 +synergy 58 +thanking 58 +tying 58 +unlocks 58 +select fld3,companynr from t2 where companynr = 58 order by fld3; +fld3 companynr +concoct 58 +druggists 58 +engrossing 58 +Eurydice 58 +exclaimers 58 +ferociousness 58 +hopelessness 58 +Huey 58 +imaginable 58 +judges 58 +merging 58 +ostrich 58 +peering 58 +Phelps 58 +presumes 58 +Ruth 58 +sentences 58 +Shylock 58 +straggled 58 +synergy 58 +thanking 58 +tying 58 +unlocks 58 +select fld3 from t2 order by fld3 desc limit 10; +fld3 +youthfulness +yelped +Wotan +workers +Witt +witchcraft +Winsett +Willy +willed +wildcats +select fld3 from t2 order by fld3 desc limit 5; +fld3 +youthfulness +yelped +Wotan +workers +Witt +select fld3 from t2 order by fld3 desc limit 5,5; +fld3 +witchcraft +Winsett +Willy +willed +wildcats +select t2.fld3 from t2 where fld3 = 'honeysuckle'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckl_'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'hon_ysuckl_'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckle%'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'h%le'; +fld3 +honeysuckle +select t2.fld3 from t2 where fld3 LIKE 'honeysuckle_'; +fld3 +select t2.fld3 from t2 where fld3 LIKE 'don_t_find_me_please%'; +fld3 +explain select t2.fld3 from t2 where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 ignore index (fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select fld3 from t2 use index (fld1) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select fld3 from t2 use index (fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 use index (fld1,fld3) where fld3 = 'honeysuckle'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref fld3 fld3 30 const 1 Using where; Using index +explain select fld3 from t2 ignore index (fld3,not_used); +ERROR HY000: Key 'not_used' doesn't exist in table 't2' +explain select fld3 from t2 use index (not_used); +ERROR HY000: Key 'not_used' doesn't exist in table 't2' +select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +fld3 +honeysuckle +honoring +explain select t2.fld3 from t2 where fld3 >= 'honeysuckle' and fld3 <= 'honoring' order by fld3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld3 fld3 30 NULL 2 Using where; Using index +select fld1,fld3 from t2 where fld3="Colombo" or fld3 = "nondecreasing" order by fld3; +fld1 fld3 +148504 Colombo +068305 Colombo +000000 nondecreasing +select fld1,fld3 from t2 where companynr = 37 and fld3 = 'appendixes'; +fld1 fld3 +232605 appendixes +1232605 appendixes +1232606 appendixes +1232607 appendixes +1232608 appendixes +1232609 appendixes +select fld1 from t2 where fld1=250501 or fld1="250502"; +fld1 +250501 +250502 +explain select fld1 from t2 where fld1=250501 or fld1="250502"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld1 fld1 4 NULL 2 Using where; Using index +select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502; +fld1 +250501 +250502 +250505 +250601 +explain select fld1 from t2 where fld1=250501 or fld1=250502 or fld1 >= 250505 and fld1 <= 250601 or fld1 between 250501 and 250502; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 range fld1 fld1 4 NULL 4 Using where; Using index +select fld1,fld3 from t2 where companynr = 37 and fld3 like 'f%'; +fld1 fld3 +218401 faithful +018007 fanatic +228311 fated +018017 featherweight +218022 feed +088303 feminine +058004 Fenton +038017 fetched +018054 fetters +208101 fiftieth +238007 filial +013606 fingerings +218008 finishers +038205 firearm +188505 fitting +202301 Fitzpatrick +238008 fixedly +012001 flanking +018103 flint +018104 flopping +188007 flurried +013602 foldout +226205 foothill +232102 forgivably +228306 forthcoming +186002 freakish +208113 freest +231315 freezes +036002 funereal +226209 furnishings +198006 furthermore +select fld3 from t2 where fld3 like "L%" and fld3 = "ok"; +fld3 +select fld3 from t2 where (fld3 like "C%" and fld3 = "Chantilly"); +fld3 +Chantilly +select fld1,fld3 from t2 where fld1 like "25050%"; +fld1 fld3 +250501 poisoning +250502 Iraqis +250503 heaving +250504 population +250505 bomb +select fld1,fld3 from t2 where fld1 like "25050_"; +fld1 fld3 +250501 poisoning +250502 Iraqis +250503 heaving +250504 population +250505 bomb +select distinct companynr from t2; +companynr +00 +37 +36 +50 +58 +29 +40 +53 +65 +41 +34 +68 +select distinct companynr from t2 order by companynr; +companynr +00 +29 +34 +36 +37 +40 +41 +50 +53 +58 +65 +68 +select distinct companynr from t2 order by companynr desc; +companynr +68 +65 +58 +53 +50 +41 +40 +37 +36 +34 +29 +00 +select distinct t2.fld3,period from t2,t1 where companynr=37 and fld3 like "O%"; +fld3 period +obliterates 9410 +offload 9410 +opaquely 9410 +organizer 9410 +overestimating 9410 +overlay 9410 +select distinct fld3 from t2 where companynr = 34 order by fld3; +fld3 +absentee +accessed +ahead +alphabetic +Asiaticizations +attitude +aye +bankruptcies +belays +Blythe +bomb +boulevard +bulldozes +cannot +caressing +charcoal +checksumming +chess +clubroom +colorful +cosy +creator +crying +Darius +diffusing +duality +Eiffel +Epiphany +Ernestine +explorers +exterminated +famine +forked +Gershwins +heaving +Hodges +Iraqis +Italianization +Lagos +landslide +libretto +Majorca +mastering +narrowed +occurred +offerers +Palestine +Peruvianizes +pharmaceutic +poisoning +population +Pygmalion +rats +realest +recording +regimented +retransmitting +reviver +rouses +scars +sicker +sleepwalk +stopped +sugars +translatable +uncles +unexpected +uprisings +versatility +vest +select distinct fld3 from t2 limit 10; +fld3 +abates +abiding +Abraham +abrogating +absentee +abut +accessed +accruing +accumulating +accuracies +select distinct fld3 from t2 having fld3 like "A%" limit 10; +fld3 +abates +abiding +Abraham +abrogating +absentee +abut +accessed +accruing +accumulating +accuracies +select distinct substring(fld3,1,3) from t2 where fld3 like "A%"; +substring(fld3,1,3) +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +Adl +adm +Ado +ads +adv +aer +aff +afi +afl +afo +agi +ahe +aim +air +Ald +alg +ali +all +alp +alr +ama +ame +amm +ana +and +ane +Ang +ani +Ann +Ant +api +app +aqu +Ara +arc +Arm +arr +Art +Asi +ask +asp +ass +ast +att +aud +Aug +aut +ave +avo +awe +aye +Azt +select distinct substring(fld3,1,3) as a from t2 having a like "A%" order by a limit 10; +a +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +select distinct substring(fld3,1,3) from t2 where fld3 like "A%" limit 10; +substring(fld3,1,3) +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +select distinct substring(fld3,1,3) as a from t2 having a like "A%" limit 10; +a +aba +abi +Abr +abs +abu +acc +acq +acu +Ade +adj +create table t3 ( +period int not null, +name char(32) not null, +companynr int not null, +price double(11,0), +price2 double(11,0), +key (period), +key (name) +); +create temporary table tmp engine = myisam select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +insert into tmp select * from t3; +insert into t3 select * from tmp; +alter table t3 add t2nr int not null auto_increment primary key first; +drop table tmp; +SET SQL_BIG_TABLES=1; +select distinct concat(fld3," ",fld3) as namn from t2,t3 where t2.fld1=t3.t2nr order by namn limit 10; +namn +Abraham Abraham +abrogating abrogating +admonishing admonishing +Adolph Adolph +afield afield +aging aging +ammonium ammonium +analyzable analyzable +animals animals +animized animized +SET SQL_BIG_TABLES=0; +select distinct concat(fld3," ",fld3) from t2,t3 where t2.fld1=t3.t2nr order by fld3 limit 10; +concat(fld3," ",fld3) +Abraham Abraham +abrogating abrogating +admonishing admonishing +Adolph Adolph +afield afield +aging aging +ammonium ammonium +analyzable analyzable +animals animals +animized animized +select distinct fld5 from t2 limit 10; +fld5 +neat +Steinberg +jarring +tinily +balled +persist +attainments +fanatic +measures +rightfulness +select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10; +fld3 count(*) +affixed 1 +and 1 +annoyers 1 +Anthony 1 +assayed 1 +assurers 1 +attendants 1 +bedlam 1 +bedpost 1 +boasted 1 +SET SQL_BIG_TABLES=1; +select distinct fld3,count(*) from t2 group by companynr,fld3 limit 10; +fld3 count(*) +affixed 1 +and 1 +annoyers 1 +Anthony 1 +assayed 1 +assurers 1 +attendants 1 +bedlam 1 +bedpost 1 +boasted 1 +SET SQL_BIG_TABLES=0; +select distinct fld3,repeat("a",length(fld3)),count(*) from t2 group by companynr,fld3 limit 100,10; +fld3 repeat("a",length(fld3)) count(*) +circus aaaaaa 1 +cited aaaaa 1 +Colombo aaaaaaa 1 +congresswoman aaaaaaaaaaaaa 1 +contrition aaaaaaaaaa 1 +corny aaaaa 1 +cultivation aaaaaaaaaaa 1 +definiteness aaaaaaaaaaaa 1 +demultiplex aaaaaaaaaaa 1 +disappointing aaaaaaaaaaaaa 1 +select distinct companynr,rtrim(space(512+companynr)) from t3 order by 1,2; +companynr rtrim(space(512+companynr)) +37 +78 +101 +154 +311 +447 +512 +select distinct fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by fld3; +fld3 +explain select t3.t2nr,fld3 from t2,t3 where t2.companynr = 34 and t2.fld1=t3.t2nr order by t3.t2nr,fld3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL fld1 NULL NULL NULL 1199 Using where; Using temporary; Using filesort +1 SIMPLE t3 eq_ref PRIMARY PRIMARY 4 test.t2.fld1 1 Using where; Using index +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL period NULL NULL NULL 41810 Using temporary; Using filesort +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t3.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index period period 4 NULL 41810 +1 SIMPLE t1 ref period period 4 test.t3.period 4181 +explain select * from t3 as t1,t3 where t1.period=t3.period order by t1.period limit 10; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index period period 4 NULL 41810 +1 SIMPLE t3 ref period period 4 test.t1.period 4181 +select period from t1; +period +9410 +select period from t1 where period=1900; +period +select fld3,period from t1,t2 where fld1 = 011401 order by period; +fld3 period +breaking 9410 +select fld3,period from t2,t3 where t2.fld1 = 011401 and t2.fld1=t3.t2nr and t3.period=1001; +fld3 period +breaking 1001 +explain select fld3,period from t2,t3 where t2.fld1 = 011401 and t3.t2nr=t2.fld1 and 1001 = t3.period; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const fld1 fld1 4 const 1 +1 SIMPLE t3 const PRIMARY,period PRIMARY 4 const 1 +select fld3,period from t2,t1 where companynr*10 = 37*10; +fld3 period +breaking 9410 +Romans 9410 +intercepted 9410 +bewilderingly 9410 +astound 9410 +admonishing 9410 +sumac 9410 +flanking 9410 +combed 9410 +subjective 9410 +scatterbrain 9410 +Eulerian 9410 +Kane 9410 +overlay 9410 +perturb 9410 +goblins 9410 +annihilates 9410 +Wotan 9410 +snatching 9410 +concludes 9410 +laterally 9410 +yelped 9410 +grazing 9410 +Baird 9410 +celery 9410 +misunderstander 9410 +handgun 9410 +foldout 9410 +mystic 9410 +succumbed 9410 +Nabisco 9410 +fingerings 9410 +aging 9410 +afield 9410 +ammonium 9410 +boat 9410 +intelligibility 9410 +Augustine 9410 +teethe 9410 +dreaded 9410 +scholastics 9410 +audiology 9410 +wallet 9410 +parters 9410 +eschew 9410 +quitter 9410 +neat 9410 +Steinberg 9410 +jarring 9410 +tinily 9410 +balled 9410 +persist 9410 +attainments 9410 +fanatic 9410 +measures 9410 +rightfulness 9410 +capably 9410 +impulsive 9410 +starlet 9410 +terminators 9410 +untying 9410 +announces 9410 +featherweight 9410 +pessimist 9410 +daughter 9410 +decliner 9410 +lawgiver 9410 +stated 9410 +readable 9410 +attrition 9410 +cascade 9410 +motors 9410 +interrogate 9410 +pests 9410 +stairway 9410 +dopers 9410 +testicle 9410 +Parsifal 9410 +leavings 9410 +postulation 9410 +squeaking 9410 +contrasted 9410 +leftover 9410 +whiteners 9410 +erases 9410 +Punjab 9410 +Merritt 9410 +Quixotism 9410 +sweetish 9410 +dogging 9410 +scornfully 9410 +bellow 9410 +bills 9410 +cupboard 9410 +sureties 9410 +puddings 9410 +fetters 9410 +bivalves 9410 +incurring 9410 +Adolph 9410 +pithed 9410 +Miles 9410 +trimmings 9410 +tragedies 9410 +skulking 9410 +flint 9410 +flopping 9410 +relaxing 9410 +offload 9410 +suites 9410 +lists 9410 +animized 9410 +multilayer 9410 +standardizes 9410 +Judas 9410 +vacuuming 9410 +dentally 9410 +humanness 9410 +inch 9410 +Weissmuller 9410 +irresponsibly 9410 +luckily 9410 +culled 9410 +medical 9410 +bloodbath 9410 +subschema 9410 +animals 9410 +Micronesia 9410 +repetitions 9410 +Antares 9410 +ventilate 9410 +pityingly 9410 +interdependent 9410 +Graves 9410 +neonatal 9410 +chafe 9410 +honoring 9410 +realtor 9410 +elite 9410 +funereal 9410 +abrogating 9410 +sorters 9410 +Conley 9410 +lectured 9410 +Abraham 9410 +Hawaii 9410 +cage 9410 +hushes 9410 +Simla 9410 +reporters 9410 +Dutchman 9410 +descendants 9410 +groupings 9410 +dissociate 9410 +coexist 9410 +Beebe 9410 +Taoism 9410 +Connally 9410 +fetched 9410 +checkpoints 9410 +rusting 9410 +galling 9410 +obliterates 9410 +traitor 9410 +resumes 9410 +analyzable 9410 +terminator 9410 +gritty 9410 +firearm 9410 +minima 9410 +Selfridge 9410 +disable 9410 +witchcraft 9410 +betroth 9410 +Manhattanize 9410 +imprint 9410 +peeked 9410 +swelling 9410 +interrelationships 9410 +riser 9410 +Gandhian 9410 +peacock 9410 +bee 9410 +kanji 9410 +dental 9410 +scarf 9410 +chasm 9410 +insolence 9410 +syndicate 9410 +alike 9410 +imperial 9410 +convulsion 9410 +railway 9410 +validate 9410 +normalizes 9410 +comprehensive 9410 +chewing 9410 +denizen 9410 +schemer 9410 +chronicle 9410 +Kline 9410 +Anatole 9410 +partridges 9410 +brunch 9410 +recruited 9410 +dimensions 9410 +Chicana 9410 +announced 9410 +praised 9410 +employing 9410 +linear 9410 +quagmire 9410 +western 9410 +relishing 9410 +serving 9410 +scheduling 9410 +lore 9410 +eventful 9410 +arteriole 9410 +disentangle 9410 +cured 9410 +Fenton 9410 +avoidable 9410 +drains 9410 +detectably 9410 +husky 9410 +impelling 9410 +undoes 9410 +evened 9410 +squeezes 9410 +destroyer 9410 +rudeness 9410 +beaner 9410 +boorish 9410 +Everhart 9410 +encompass 9410 +mushrooms 9410 +Alison 9410 +externally 9410 +pellagra 9410 +cult 9410 +creek 9410 +Huffman 9410 +Majorca 9410 +governing 9410 +gadfly 9410 +reassigned 9410 +intentness 9410 +craziness 9410 +psychic 9410 +squabbled 9410 +burlesque 9410 +capped 9410 +extracted 9410 +DiMaggio 9410 +exclamation 9410 +subdirectory 9410 +Gothicism 9410 +feminine 9410 +metaphysically 9410 +sanding 9410 +Miltonism 9410 +freakish 9410 +index 9410 +straight 9410 +flurried 9410 +denotative 9410 +coming 9410 +commencements 9410 +gentleman 9410 +gifted 9410 +Shanghais 9410 +sportswriting 9410 +sloping 9410 +navies 9410 +leaflet 9410 +shooter 9410 +Joplin 9410 +babies 9410 +assails 9410 +admiring 9410 +swaying 9410 +Goldstine 9410 +fitting 9410 +Norwalk 9410 +analogy 9410 +deludes 9410 +cokes 9410 +Clayton 9410 +exhausts 9410 +causality 9410 +sating 9410 +icon 9410 +throttles 9410 +communicants 9410 +dehydrate 9410 +priceless 9410 +publicly 9410 +incidentals 9410 +commonplace 9410 +mumbles 9410 +furthermore 9410 +cautioned 9410 +parametrized 9410 +registration 9410 +sadly 9410 +positioning 9410 +babysitting 9410 +eternal 9410 +hoarder 9410 +congregates 9410 +rains 9410 +workers 9410 +sags 9410 +unplug 9410 +garage 9410 +boulder 9410 +specifics 9410 +Teresa 9410 +Winsett 9410 +convenient 9410 +buckboards 9410 +amenities 9410 +resplendent 9410 +sews 9410 +participated 9410 +Simon 9410 +certificates 9410 +Fitzpatrick 9410 +Evanston 9410 +misted 9410 +textures 9410 +save 9410 +count 9410 +rightful 9410 +chaperone 9410 +Lizzy 9410 +clenched 9410 +effortlessly 9410 +accessed 9410 +beaters 9410 +Hornblower 9410 +vests 9410 +indulgences 9410 +infallibly 9410 +unwilling 9410 +excrete 9410 +spools 9410 +crunches 9410 +overestimating 9410 +ineffective 9410 +humiliation 9410 +sophomore 9410 +star 9410 +rifles 9410 +dialysis 9410 +arriving 9410 +indulge 9410 +clockers 9410 +languages 9410 +Antarctica 9410 +percentage 9410 +ceiling 9410 +specification 9410 +regimented 9410 +ciphers 9410 +pictures 9410 +serpents 9410 +allot 9410 +realized 9410 +mayoral 9410 +opaquely 9410 +hostess 9410 +fiftieth 9410 +incorrectly 9410 +decomposition 9410 +stranglings 9410 +mixture 9410 +electroencephalography 9410 +similarities 9410 +charges 9410 +freest 9410 +Greenberg 9410 +tinting 9410 +expelled 9410 +warm 9410 +smoothed 9410 +deductions 9410 +Romano 9410 +bitterroot 9410 +corset 9410 +securing 9410 +environing 9410 +cute 9410 +Crays 9410 +heiress 9410 +inform 9410 +avenge 9410 +universals 9410 +Kinsey 9410 +ravines 9410 +bestseller 9410 +equilibrium 9410 +extents 9410 +relatively 9410 +pressure 9410 +critiques 9410 +befouled 9410 +rightfully 9410 +mechanizing 9410 +Latinizes 9410 +timesharing 9410 +Aden 9410 +embassies 9410 +males 9410 +shapelessly 9410 +mastering 9410 +Newtonian 9410 +finishers 9410 +abates 9410 +teem 9410 +kiting 9410 +stodgy 9410 +feed 9410 +guitars 9410 +airships 9410 +store 9410 +denounces 9410 +Pyle 9410 +Saxony 9410 +serializations 9410 +Peruvian 9410 +taxonomically 9410 +kingdom 9410 +stint 9410 +Sault 9410 +faithful 9410 +Ganymede 9410 +tidiness 9410 +gainful 9410 +contrary 9410 +Tipperary 9410 +tropics 9410 +theorizers 9410 +renew 9410 +already 9410 +terminal 9410 +Hegelian 9410 +hypothesizer 9410 +warningly 9410 +journalizing 9410 +nested 9410 +Lars 9410 +saplings 9410 +foothill 9410 +labeled 9410 +imperiously 9410 +reporters 9410 +furnishings 9410 +precipitable 9410 +discounts 9410 +excises 9410 +Stalin 9410 +despot 9410 +ripeness 9410 +Arabia 9410 +unruly 9410 +mournfulness 9410 +boom 9410 +slaughter 9410 +Sabine 9410 +handy 9410 +rural 9410 +organizer 9410 +shipyard 9410 +civics 9410 +inaccuracy 9410 +rules 9410 +juveniles 9410 +comprised 9410 +investigations 9410 +stabilizes 9410 +seminaries 9410 +Hunter 9410 +sporty 9410 +test 9410 +weasels 9410 +CERN 9410 +tempering 9410 +afore 9410 +Galatean 9410 +techniques 9410 +error 9410 +veranda 9410 +severely 9410 +Cassites 9410 +forthcoming 9410 +guides 9410 +vanish 9410 +lied 9410 +sawtooth 9410 +fated 9410 +gradually 9410 +widens 9410 +preclude 9410 +evenhandedly 9410 +percentage 9410 +disobedience 9410 +humility 9410 +gleaning 9410 +petted 9410 +bloater 9410 +minion 9410 +marginal 9410 +apiary 9410 +measures 9410 +precaution 9410 +repelled 9410 +primary 9410 +coverings 9410 +Artemia 9410 +navigate 9410 +spatial 9410 +Gurkha 9410 +meanwhile 9410 +Melinda 9410 +Butterfield 9410 +Aldrich 9410 +previewing 9410 +glut 9410 +unaffected 9410 +inmate 9410 +mineral 9410 +impending 9410 +meditation 9410 +ideas 9410 +miniaturizes 9410 +lewdly 9410 +title 9410 +youthfulness 9410 +creak 9410 +Chippewa 9410 +clamored 9410 +freezes 9410 +forgivably 9410 +reduce 9410 +McGovern 9410 +Nazis 9410 +epistle 9410 +socializes 9410 +conceptions 9410 +Kevin 9410 +uncovering 9410 +chews 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +appendixes 9410 +raining 9410 +infest 9410 +compartment 9410 +minting 9410 +ducks 9410 +roped 9410 +waltz 9410 +Lillian 9410 +repressions 9410 +chillingly 9410 +noncritical 9410 +lithograph 9410 +spongers 9410 +parenthood 9410 +posed 9410 +instruments 9410 +filial 9410 +fixedly 9410 +relives 9410 +Pandora 9410 +watering 9410 +ungrateful 9410 +secures 9410 +poison 9410 +dusted 9410 +encompasses 9410 +presentation 9410 +Kantian 9410 +select fld3,period,price,price2 from t2,t3 where t2.fld1=t3.t2nr and period >= 1001 and period <= 1002 and t2.companynr = 37 order by fld3,period, price; +fld3 period price price2 +admonishing 1002 28357832 8723648 +analyzable 1002 28357832 8723648 +annihilates 1001 5987435 234724 +Antares 1002 28357832 8723648 +astound 1001 5987435 234724 +audiology 1001 5987435 234724 +Augustine 1002 28357832 8723648 +Baird 1002 28357832 8723648 +bewilderingly 1001 5987435 234724 +breaking 1001 5987435 234724 +Conley 1001 5987435 234724 +dentally 1002 28357832 8723648 +dissociate 1002 28357832 8723648 +elite 1001 5987435 234724 +eschew 1001 5987435 234724 +Eulerian 1001 5987435 234724 +flanking 1001 5987435 234724 +foldout 1002 28357832 8723648 +funereal 1002 28357832 8723648 +galling 1002 28357832 8723648 +Graves 1001 5987435 234724 +grazing 1001 5987435 234724 +groupings 1001 5987435 234724 +handgun 1001 5987435 234724 +humility 1002 28357832 8723648 +impulsive 1002 28357832 8723648 +inch 1001 5987435 234724 +intelligibility 1001 5987435 234724 +jarring 1001 5987435 234724 +lawgiver 1001 5987435 234724 +lectured 1002 28357832 8723648 +Merritt 1002 28357832 8723648 +neonatal 1001 5987435 234724 +offload 1002 28357832 8723648 +parters 1002 28357832 8723648 +pityingly 1002 28357832 8723648 +puddings 1002 28357832 8723648 +Punjab 1001 5987435 234724 +quitter 1002 28357832 8723648 +realtor 1001 5987435 234724 +relaxing 1001 5987435 234724 +repetitions 1001 5987435 234724 +resumes 1001 5987435 234724 +Romans 1002 28357832 8723648 +rusting 1001 5987435 234724 +scholastics 1001 5987435 234724 +skulking 1002 28357832 8723648 +stated 1002 28357832 8723648 +suites 1002 28357832 8723648 +sureties 1001 5987435 234724 +testicle 1002 28357832 8723648 +tinily 1002 28357832 8723648 +tragedies 1001 5987435 234724 +trimmings 1001 5987435 234724 +vacuuming 1001 5987435 234724 +ventilate 1001 5987435 234724 +wallet 1001 5987435 234724 +Weissmuller 1002 28357832 8723648 +Wotan 1002 28357832 8723648 +select t2.fld1,fld3,period,price,price2 from t2,t3 where t2.fld1>= 18201 and t2.fld1 <= 18811 and t2.fld1=t3.t2nr and period = 1001 and t2.companynr = 37; +fld1 fld3 period price price2 +018201 relaxing 1001 5987435 234724 +018601 vacuuming 1001 5987435 234724 +018801 inch 1001 5987435 234724 +018811 repetitions 1001 5987435 234724 +create table t4 ( +companynr tinyint(2) unsigned zerofill NOT NULL default '00', +companyname char(30) NOT NULL default '', +PRIMARY KEY (companynr), +UNIQUE KEY companyname(companyname) +) ENGINE=MyISAM MAX_ROWS=50 PACK_KEYS=1 COMMENT='companynames'; +select STRAIGHT_JOIN t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; +companynr companyname +00 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select SQL_SMALL_RESULT t2.companynr,companyname from t4,t2 where t2.companynr=t4.companynr group by t2.companynr; +companynr companyname +00 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select * from t1,t1 t12; +Period Varor_period Period Varor_period +9410 9412 9410 9412 +select t2.fld1,t22.fld1 from t2,t2 t22 where t2.fld1 >= 250501 and t2.fld1 <= 250505 and t22.fld1 >= 250501 and t22.fld1 <= 250505; +fld1 fld1 +250501 250501 +250502 250501 +250503 250501 +250504 250501 +250505 250501 +250501 250502 +250502 250502 +250503 250502 +250504 250502 +250505 250502 +250501 250503 +250502 250503 +250503 250503 +250504 250503 +250505 250503 +250501 250504 +250502 250504 +250503 250504 +250504 250504 +250505 250504 +250501 250505 +250502 250505 +250503 250505 +250504 250505 +250505 250505 +insert into t2 (fld1, companynr) values (999999,99); +select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +companynr companyname +99 NULL +select count(*) from t2 left join t4 using (companynr) where t4.companynr is not null; +count(*) +1199 +explain select t2.companynr,companyname from t2 left join t4 using (companynr) where t4.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 Using where; Not exists +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1200 Using where; Not exists +select companynr,companyname from t2 left join t4 using (companynr) where companynr is null; +companynr companyname +select count(*) from t2 left join t4 using (companynr) where companynr is not null; +count(*) +1200 +explain select companynr,companyname from t2 left join t4 using (companynr) where companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +delete from t2 where fld1=999999; +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 and t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +1 SIMPLE t4 eq_ref PRIMARY PRIMARY 1 test.t2.companynr 1 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 and companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where t2.companynr > 0 or t2.companynr < 0 or t4.companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select t2.companynr,companyname from t4 left join t2 using (companynr) where ifnull(t2.companynr,1)>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where companynr > 0 or companynr < 0 or companynr > 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL PRIMARY NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +explain select companynr,companyname from t4 left join t2 using (companynr) where ifnull(companynr,1)>0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 12 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +companynr companynr +37 36 +41 40 +explain select distinct t2.companynr,t4.companynr from t2,t4 where t2.companynr=t4.companynr+1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t4 index NULL PRIMARY 1 NULL 12 Using index; Using temporary +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +select t2.fld1,t2.companynr,fld3,period from t3,t2 where t2.fld1 = 38208 and t2.fld1=t3.t2nr and period = 1008 or t2.fld1 = 38008 and t2.fld1 =t3.t2nr and period = 1008; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t2.fld1 = 38208 or t2.fld1 = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select t2.fld1,t2.companynr,fld3,period from t3,t2 where (t3.t2nr = 38208 or t3.t2nr = 38008) and t2.fld1=t3.t2nr and period>=1008 and period<=1009; +fld1 companynr fld3 period +038008 37 reporters 1008 +038208 37 Selfridge 1008 +select period from t1 where (((period > 0) or period < 10000 or (period = 1900)) and (period=1900 and period <= 1901) or (period=1903 and (period=1903)) and period>=1902) or ((period=1904 or period=1905) or (period=1906 or period>1907)) or (period=1908 and period = 1909); +period +9410 +select period from t1 where ((period > 0 and period < 1) or (((period > 0 and period < 100) and (period > 10)) or (period > 10)) or (period > 0 and (period > 5 or period > 6))); +period +9410 +select a.fld1 from t2 as a,t2 b where ((a.fld1 = 250501 and a.fld1=b.fld1) or a.fld1=250502 or a.fld1=250503 or (a.fld1=250505 and a.fld1<=b.fld1 and b.fld1>=a.fld1)) and a.fld1=b.fld1; +fld1 +250501 +250502 +250503 +250505 +select fld1 from t2 where fld1 in (250502,98005,98006,250503,250605,250606) and fld1 >=250502 and fld1 not in (250605,250606); +fld1 +250502 +250503 +select fld1 from t2 where fld1 between 250502 and 250504; +fld1 +250502 +250503 +250504 +select fld3 from t2 where (((fld3 like "_%L%" ) or (fld3 like "%ok%")) and ( fld3 like "L%" or fld3 like "G%")) and fld3 like "L%" ; +fld3 +label +labeled +labeled +landslide +laterally +leaflet +lewdly +Lillian +luckily +select count(*) from t1; +count(*) +1 +select companynr,count(*),sum(fld1) from t2 group by companynr; +companynr count(*) sum(fld1) +00 82 10355753 +29 95 14473298 +34 70 17788966 +36 215 22786296 +37 588 83602098 +40 37 6618386 +41 52 12816335 +50 11 1595438 +53 4 793210 +58 23 2254293 +65 10 2284055 +68 12 3097288 +select companynr,count(*) from t2 group by companynr order by companynr desc limit 5; +companynr count(*) +68 12 +65 10 +58 23 +53 4 +50 11 +select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; +count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) +70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 +explain extended select count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 where companynr = 34 and fld4<>""; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 Using where +Warnings: +Note 1003 select count(0) AS `count(*)`,min(`test`.`t2`.`fld4`) AS `min(fld4)`,max(`test`.`t2`.`fld4`) AS `max(fld4)`,sum(`test`.`t2`.`fld1`) AS `sum(fld1)`,avg(`test`.`t2`.`fld1`) AS `avg(fld1)`,std(`test`.`t2`.`fld1`) AS `std(fld1)`,variance(`test`.`t2`.`fld1`) AS `variance(fld1)` from `test`.`t2` where ((`test`.`t2`.`companynr` = 34) and (`test`.`t2`.`fld4` <> _latin1'')) +select companynr,count(*),min(fld4),max(fld4),sum(fld1),avg(fld1),std(fld1),variance(fld1) from t2 group by companynr limit 3; +companynr count(*) min(fld4) max(fld4) sum(fld1) avg(fld1) std(fld1) variance(fld1) +00 82 Anthony windmills 10355753 126289.6707 115550.9757 13352027981.7087 +29 95 abut wetness 14473298 152350.5053 8368.5480 70032594.9026 +34 70 absentee vest 17788966 254128.0857 3272.5940 10709871.3069 +select companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10; +companynr t2nr count(price) sum(price) min(price) max(price) avg(price) +37 1 1 5987435 5987435 5987435 5987435.0000 +37 2 1 28357832 28357832 28357832 28357832.0000 +37 3 1 39654943 39654943 39654943 39654943.0000 +37 11 1 5987435 5987435 5987435 5987435.0000 +37 12 1 28357832 28357832 28357832 28357832.0000 +37 13 1 39654943 39654943 39654943 39654943.0000 +37 21 1 5987435 5987435 5987435 5987435.0000 +37 22 1 28357832 28357832 28357832 28357832.0000 +37 23 1 39654943 39654943 39654943 39654943.0000 +37 31 1 5987435 5987435 5987435 5987435.0000 +select /*! SQL_SMALL_RESULT */ companynr,t2nr,count(price),sum(price),min(price),max(price),avg(price) from t3 where companynr = 37 group by companynr,t2nr limit 10; +companynr t2nr count(price) sum(price) min(price) max(price) avg(price) +37 1 1 5987435 5987435 5987435 5987435.0000 +37 2 1 28357832 28357832 28357832 28357832.0000 +37 3 1 39654943 39654943 39654943 39654943.0000 +37 11 1 5987435 5987435 5987435 5987435.0000 +37 12 1 28357832 28357832 28357832 28357832.0000 +37 13 1 39654943 39654943 39654943 39654943.0000 +37 21 1 5987435 5987435 5987435 5987435.0000 +37 22 1 28357832 28357832 28357832 28357832.0000 +37 23 1 39654943 39654943 39654943 39654943.0000 +37 31 1 5987435 5987435 5987435 5987435.0000 +select companynr,count(price),sum(price),min(price),max(price),avg(price) from t3 group by companynr ; +companynr count(price) sum(price) min(price) max(price) avg(price) +37 12543 309394878010 5987435 39654943 24666736.6667 +78 8362 414611089292 726498 98439034 49582766.0000 +101 4181 3489454238 834598 834598 834598.0000 +154 4181 4112197254950 983543950 983543950 983543950.0000 +311 4181 979599938 234298 234298 234298.0000 +447 4181 9929180954 2374834 2374834 2374834.0000 +512 4181 3288532102 786542 786542 786542.0000 +select distinct mod(companynr,10) from t4 group by companynr; +mod(companynr,10) +0 +9 +4 +6 +7 +1 +3 +8 +5 +select distinct 1 from t4 group by companynr; +1 +1 +select count(distinct fld1) from t2; +count(distinct fld1) +1199 +select companynr,count(distinct fld1) from t2 group by companynr; +companynr count(distinct fld1) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(*) from t2 group by companynr; +companynr count(*) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct concat(fld1,repeat(65,1000))) from t2 group by companynr; +companynr count(distinct concat(fld1,repeat(65,1000))) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct concat(fld1,repeat(65,200))) from t2 group by companynr; +companynr count(distinct concat(fld1,repeat(65,200))) +00 82 +29 95 +34 70 +36 215 +37 588 +40 37 +41 52 +50 11 +53 4 +58 23 +65 10 +68 12 +select companynr,count(distinct floor(fld1/100)) from t2 group by companynr; +companynr count(distinct floor(fld1/100)) +00 47 +29 35 +34 14 +36 69 +37 108 +40 16 +41 11 +50 9 +53 1 +58 1 +65 1 +68 1 +select companynr,count(distinct concat(repeat(65,1000),floor(fld1/100))) from t2 group by companynr; +companynr count(distinct concat(repeat(65,1000),floor(fld1/100))) +00 47 +29 35 +34 14 +36 69 +37 108 +40 16 +41 11 +50 9 +53 1 +58 1 +65 1 +68 1 +select sum(fld1),fld3 from t2 where fld3="Romans" group by fld1 limit 10; +sum(fld1) fld3 +11402 Romans +select name,count(*) from t3 where name='cloakroom' group by name; +name count(*) +cloakroom 4181 +select name,count(*) from t3 where name='cloakroom' and price>10 group by name; +name count(*) +cloakroom 4181 +select count(*) from t3 where name='cloakroom' and price2=823742; +count(*) +4181 +select name,count(*) from t3 where name='cloakroom' and price2=823742 group by name; +name count(*) +cloakroom 4181 +select name,count(*) from t3 where name >= "extramarital" and price <= 39654943 group by name; +name count(*) +extramarital 4181 +gazer 4181 +gems 4181 +Iranizes 4181 +spates 4181 +tucked 4181 +violinist 4181 +select t2.fld3,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name; +fld3 count(*) +spates 4181 +select companynr|0,companyname from t4 group by 1; +companynr|0 companyname +0 Unknown +29 company 1 +34 company 2 +36 company 3 +37 company 4 +40 company 5 +41 company 6 +50 company 11 +53 company 7 +58 company 8 +65 company 9 +68 company 10 +select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by t2.companynr order by companyname; +companynr companyname count(*) +29 company 1 95 +68 company 10 12 +50 company 11 11 +34 company 2 70 +36 company 3 215 +37 company 4 588 +40 company 5 37 +41 company 6 52 +53 company 7 4 +58 company 8 23 +65 company 9 10 +00 Unknown 82 +select t2.fld1,count(*) from t2,t3 where t2.fld1=158402 and t3.name=t2.fld3 group by t3.name; +fld1 count(*) +158402 4181 +select sum(Period)/count(*) from t1; +sum(Period)/count(*) +9410.0000 +select companynr,count(price) as "count",sum(price) as "sum" ,abs(sum(price)/count(price)-avg(price)) as "diff",(0+count(price))*companynr as func from t3 group by companynr; +companynr count sum diff func +37 12543 309394878010 0.0000 464091 +78 8362 414611089292 0.0000 652236 +101 4181 3489454238 0.0000 422281 +154 4181 4112197254950 0.0000 643874 +311 4181 979599938 0.0000 1300291 +447 4181 9929180954 0.0000 1868907 +512 4181 3288532102 0.0000 2140672 +select companynr,sum(price)/count(price) as avg from t3 group by companynr having avg > 70000000 order by avg; +companynr avg +154 983543950.0000 +select companynr,count(*) from t2 group by companynr order by 2 desc; +companynr count(*) +37 588 +36 215 +29 95 +00 82 +34 70 +41 52 +40 37 +58 23 +68 12 +50 11 +65 10 +53 4 +select companynr,count(*) from t2 where companynr > 40 group by companynr order by 2 desc; +companynr count(*) +41 52 +58 23 +68 12 +50 11 +65 10 +53 4 +select t2.fld4,t2.fld1,count(price),sum(price),min(price),max(price),avg(price) from t3,t2 where t3.companynr = 37 and t2.fld1 = t3.t2nr group by fld1,t2.fld4; +fld4 fld1 count(price) sum(price) min(price) max(price) avg(price) +teethe 000001 1 5987435 5987435 5987435 5987435.0000 +dreaded 011401 1 5987435 5987435 5987435 5987435.0000 +scholastics 011402 1 28357832 28357832 28357832 28357832.0000 +audiology 011403 1 39654943 39654943 39654943 39654943.0000 +wallet 011501 1 5987435 5987435 5987435 5987435.0000 +parters 011701 1 5987435 5987435 5987435 5987435.0000 +eschew 011702 1 28357832 28357832 28357832 28357832.0000 +quitter 011703 1 39654943 39654943 39654943 39654943.0000 +neat 012001 1 5987435 5987435 5987435 5987435.0000 +Steinberg 012003 1 39654943 39654943 39654943 39654943.0000 +balled 012301 1 5987435 5987435 5987435 5987435.0000 +persist 012302 1 28357832 28357832 28357832 28357832.0000 +attainments 012303 1 39654943 39654943 39654943 39654943.0000 +capably 012501 1 5987435 5987435 5987435 5987435.0000 +impulsive 012602 1 28357832 28357832 28357832 28357832.0000 +starlet 012603 1 39654943 39654943 39654943 39654943.0000 +featherweight 012701 1 5987435 5987435 5987435 5987435.0000 +pessimist 012702 1 28357832 28357832 28357832 28357832.0000 +daughter 012703 1 39654943 39654943 39654943 39654943.0000 +lawgiver 013601 1 5987435 5987435 5987435 5987435.0000 +stated 013602 1 28357832 28357832 28357832 28357832.0000 +readable 013603 1 39654943 39654943 39654943 39654943.0000 +testicle 013801 1 5987435 5987435 5987435 5987435.0000 +Parsifal 013802 1 28357832 28357832 28357832 28357832.0000 +leavings 013803 1 39654943 39654943 39654943 39654943.0000 +squeaking 013901 1 5987435 5987435 5987435 5987435.0000 +contrasted 016001 1 5987435 5987435 5987435 5987435.0000 +leftover 016201 1 5987435 5987435 5987435 5987435.0000 +whiteners 016202 1 28357832 28357832 28357832 28357832.0000 +erases 016301 1 5987435 5987435 5987435 5987435.0000 +Punjab 016302 1 28357832 28357832 28357832 28357832.0000 +Merritt 016303 1 39654943 39654943 39654943 39654943.0000 +sweetish 018001 1 5987435 5987435 5987435 5987435.0000 +dogging 018002 1 28357832 28357832 28357832 28357832.0000 +scornfully 018003 1 39654943 39654943 39654943 39654943.0000 +fetters 018012 1 28357832 28357832 28357832 28357832.0000 +bivalves 018013 1 39654943 39654943 39654943 39654943.0000 +skulking 018021 1 5987435 5987435 5987435 5987435.0000 +flint 018022 1 28357832 28357832 28357832 28357832.0000 +flopping 018023 1 39654943 39654943 39654943 39654943.0000 +Judas 018032 1 28357832 28357832 28357832 28357832.0000 +vacuuming 018033 1 39654943 39654943 39654943 39654943.0000 +medical 018041 1 5987435 5987435 5987435 5987435.0000 +bloodbath 018042 1 28357832 28357832 28357832 28357832.0000 +subschema 018043 1 39654943 39654943 39654943 39654943.0000 +interdependent 018051 1 5987435 5987435 5987435 5987435.0000 +Graves 018052 1 28357832 28357832 28357832 28357832.0000 +neonatal 018053 1 39654943 39654943 39654943 39654943.0000 +sorters 018061 1 5987435 5987435 5987435 5987435.0000 +epistle 018062 1 28357832 28357832 28357832 28357832.0000 +Conley 018101 1 5987435 5987435 5987435 5987435.0000 +lectured 018102 1 28357832 28357832 28357832 28357832.0000 +Abraham 018103 1 39654943 39654943 39654943 39654943.0000 +cage 018201 1 5987435 5987435 5987435 5987435.0000 +hushes 018202 1 28357832 28357832 28357832 28357832.0000 +Simla 018402 1 28357832 28357832 28357832 28357832.0000 +reporters 018403 1 39654943 39654943 39654943 39654943.0000 +coexist 018601 1 5987435 5987435 5987435 5987435.0000 +Beebe 018602 1 28357832 28357832 28357832 28357832.0000 +Taoism 018603 1 39654943 39654943 39654943 39654943.0000 +Connally 018801 1 5987435 5987435 5987435 5987435.0000 +fetched 018802 1 28357832 28357832 28357832 28357832.0000 +checkpoints 018803 1 39654943 39654943 39654943 39654943.0000 +gritty 018811 1 5987435 5987435 5987435 5987435.0000 +firearm 018812 1 28357832 28357832 28357832 28357832.0000 +minima 019101 1 5987435 5987435 5987435 5987435.0000 +Selfridge 019102 1 28357832 28357832 28357832 28357832.0000 +disable 019103 1 39654943 39654943 39654943 39654943.0000 +witchcraft 019201 1 5987435 5987435 5987435 5987435.0000 +betroth 030501 1 5987435 5987435 5987435 5987435.0000 +Manhattanize 030502 1 28357832 28357832 28357832 28357832.0000 +imprint 030503 1 39654943 39654943 39654943 39654943.0000 +swelling 031901 1 5987435 5987435 5987435 5987435.0000 +interrelationships 036001 1 5987435 5987435 5987435 5987435.0000 +riser 036002 1 28357832 28357832 28357832 28357832.0000 +bee 038001 1 5987435 5987435 5987435 5987435.0000 +kanji 038002 1 28357832 28357832 28357832 28357832.0000 +dental 038003 1 39654943 39654943 39654943 39654943.0000 +railway 038011 1 5987435 5987435 5987435 5987435.0000 +validate 038012 1 28357832 28357832 28357832 28357832.0000 +normalizes 038013 1 39654943 39654943 39654943 39654943.0000 +Kline 038101 1 5987435 5987435 5987435 5987435.0000 +Anatole 038102 1 28357832 28357832 28357832 28357832.0000 +partridges 038103 1 39654943 39654943 39654943 39654943.0000 +recruited 038201 1 5987435 5987435 5987435 5987435.0000 +dimensions 038202 1 28357832 28357832 28357832 28357832.0000 +Chicana 038203 1 39654943 39654943 39654943 39654943.0000 +select t3.companynr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 group by companynr,fld3; +companynr fld3 sum(price) +512 boat 786542 +512 capably 786542 +512 cupboard 786542 +512 decliner 786542 +512 descendants 786542 +512 dopers 786542 +512 erases 786542 +512 Micronesia 786542 +512 Miles 786542 +512 skies 786542 +select t2.companynr,count(*),min(fld3),max(fld3),sum(price),avg(price) from t2,t3 where t3.companynr >= 30 and t3.companynr <= 58 and t3.t2nr = t2.fld1 and 1+1=2 group by t2.companynr; +companynr count(*) min(fld3) max(fld3) sum(price) avg(price) +00 1 Omaha Omaha 5987435 5987435.0000 +36 1 dubbed dubbed 28357832 28357832.0000 +37 83 Abraham Wotan 1908978016 22999735.1325 +50 2 scribbled tapestry 68012775 34006387.5000 +select t3.companynr+0,t3.t2nr,fld3,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 37 group by 1,t3.t2nr,fld3,fld3,fld3,fld3,fld3 order by fld1; +t3.companynr+0 t2nr fld3 sum(price) +37 1 Omaha 5987435 +37 11401 breaking 5987435 +37 11402 Romans 28357832 +37 11403 intercepted 39654943 +37 11501 bewilderingly 5987435 +37 11701 astound 5987435 +37 11702 admonishing 28357832 +37 11703 sumac 39654943 +37 12001 flanking 5987435 +37 12003 combed 39654943 +37 12301 Eulerian 5987435 +37 12302 dubbed 28357832 +37 12303 Kane 39654943 +37 12501 annihilates 5987435 +37 12602 Wotan 28357832 +37 12603 snatching 39654943 +37 12701 grazing 5987435 +37 12702 Baird 28357832 +37 12703 celery 39654943 +37 13601 handgun 5987435 +37 13602 foldout 28357832 +37 13603 mystic 39654943 +37 13801 intelligibility 5987435 +37 13802 Augustine 28357832 +37 13803 teethe 39654943 +37 13901 scholastics 5987435 +37 16001 audiology 5987435 +37 16201 wallet 5987435 +37 16202 parters 28357832 +37 16301 eschew 5987435 +37 16302 quitter 28357832 +37 16303 neat 39654943 +37 18001 jarring 5987435 +37 18002 tinily 28357832 +37 18003 balled 39654943 +37 18012 impulsive 28357832 +37 18013 starlet 39654943 +37 18021 lawgiver 5987435 +37 18022 stated 28357832 +37 18023 readable 39654943 +37 18032 testicle 28357832 +37 18033 Parsifal 39654943 +37 18041 Punjab 5987435 +37 18042 Merritt 28357832 +37 18043 Quixotism 39654943 +37 18051 sureties 5987435 +37 18052 puddings 28357832 +37 18053 tapestry 39654943 +37 18061 trimmings 5987435 +37 18062 humility 28357832 +37 18101 tragedies 5987435 +37 18102 skulking 28357832 +37 18103 flint 39654943 +37 18201 relaxing 5987435 +37 18202 offload 28357832 +37 18402 suites 28357832 +37 18403 lists 39654943 +37 18601 vacuuming 5987435 +37 18602 dentally 28357832 +37 18603 humanness 39654943 +37 18801 inch 5987435 +37 18802 Weissmuller 28357832 +37 18803 irresponsibly 39654943 +37 18811 repetitions 5987435 +37 18812 Antares 28357832 +37 19101 ventilate 5987435 +37 19102 pityingly 28357832 +37 19103 interdependent 39654943 +37 19201 Graves 5987435 +37 30501 neonatal 5987435 +37 30502 scribbled 28357832 +37 30503 chafe 39654943 +37 31901 realtor 5987435 +37 36001 elite 5987435 +37 36002 funereal 28357832 +37 38001 Conley 5987435 +37 38002 lectured 28357832 +37 38003 Abraham 39654943 +37 38011 groupings 5987435 +37 38012 dissociate 28357832 +37 38013 coexist 39654943 +37 38101 rusting 5987435 +37 38102 galling 28357832 +37 38103 obliterates 39654943 +37 38201 resumes 5987435 +37 38202 analyzable 28357832 +37 38203 terminator 39654943 +select sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1= t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008; +sum(price) +234298 +select t2.fld1,sum(price) from t3,t2 where t2.fld1 = t3.t2nr and t3.companynr = 512 and t3.t2nr = 38008 and t2.fld1 = 38008 or t2.fld1 = t3.t2nr and t3.t2nr = 38008 and t2.fld1 = 38008 or t3.t2nr = t2.fld1 and t2.fld1 = 38008 group by t2.fld1; +fld1 sum(price) +038008 234298 +explain select fld3 from t2 where 1>2 or 2>3; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +explain select fld3 from t2 where fld1=fld1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 1199 +select companynr,fld1 from t2 HAVING fld1=250501 or fld1=250502; +companynr fld1 +34 250501 +34 250502 +select companynr,fld1 from t2 WHERE fld1>=250501 HAVING fld1<=250502; +companynr fld1 +34 250501 +34 250502 +select companynr,count(*) as count,sum(fld1) as sum from t2 group by companynr having count > 40 and sum/count >= 120000; +companynr count sum +00 82 10355753 +29 95 14473298 +34 70 17788966 +37 588 83602098 +41 52 12816335 +select companynr from t2 group by companynr having count(*) > 40 and sum(fld1)/count(*) >= 120000 ; +companynr +00 +29 +34 +37 +41 +select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.companynr group by companyname having t2.companynr >= 40; +companynr companyname count(*) +68 company 10 12 +50 company 11 11 +40 company 5 37 +41 company 6 52 +53 company 7 4 +58 company 8 23 +65 company 9 10 +select count(*) from t2; +count(*) +1199 +select count(*) from t2 where fld1 < 098024; +count(*) +387 +select min(fld1) from t2 where fld1>= 098024; +min(fld1) +98024 +select max(fld1) from t2 where fld1>= 098024; +max(fld1) +1232609 +select count(*) from t3 where price2=76234234; +count(*) +4181 +select count(*) from t3 where companynr=512 and price2=76234234; +count(*) +4181 +explain select min(fld1),max(fld1),count(*) from t2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +select min(fld1),max(fld1),count(*) from t2; +min(fld1) max(fld1) count(*) +0 1232609 1199 +select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742; +min(t2nr) max(t2nr) +2115 2115 +select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78; +count(*) min(t2nr) max(t2nr) +4181 4 41804 +select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20; +t2nr count(*) +9 1 +19 1 +29 1 +39 1 +49 1 +59 1 +69 1 +79 1 +89 1 +99 1 +109 1 +119 1 +129 1 +139 1 +149 1 +159 1 +169 1 +179 1 +189 1 +199 1 +select max(t2nr) from t3 where price=983543950; +max(t2nr) +41807 +select t1.period from t3 = t1 limit 1; +period +1001 +select t1.period from t1 as t1 limit 1; +period +9410 +select t1.period as "Nuvarande period" from t1 as t1 limit 1; +Nuvarande period +9410 +select period as ok_period from t1 limit 1; +ok_period +9410 +select period as ok_period from t1 group by ok_period limit 1; +ok_period +9410 +select 1+1 as summa from t1 group by summa limit 1; +summa +2 +select period as "Nuvarande period" from t1 group by "Nuvarande period" limit 1; +Nuvarande period +9410 +show tables; +Tables_in_test +t1 +t2 +t3 +t4 +show tables from test like "s%"; +Tables_in_test (s%) +show tables from test like "t?"; +Tables_in_test (t?) +show full columns from t2; +Field Type Collation Null Key Default Extra Privileges Comment +auto int(11) NULL NO PRI NULL auto_increment # +fld1 int(6) unsigned zerofill NULL NO UNI 000000 # +companynr tinyint(2) unsigned zerofill NULL NO 00 # +fld3 char(30) latin1_swedish_ci NO MUL # +fld4 char(35) latin1_swedish_ci NO # +fld5 char(35) latin1_swedish_ci NO # +fld6 char(4) latin1_swedish_ci NO # +show full columns from t2 from test like 'f%'; +Field Type Collation Null Key Default Extra Privileges Comment +fld1 int(6) unsigned zerofill NULL NO UNI 000000 # +fld3 char(30) latin1_swedish_ci NO MUL # +fld4 char(35) latin1_swedish_ci NO # +fld5 char(35) latin1_swedish_ci NO # +fld6 char(4) latin1_swedish_ci NO # +show full columns from t2 from test like 's%'; +Field Type Collation Null Key Default Extra Privileges Comment +show keys from t2; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment +t2 0 PRIMARY 1 auto A 1199 NULL NULL BTREE +t2 0 fld1 1 fld1 A 1199 NULL NULL BTREE +t2 1 fld3 1 fld3 A NULL NULL NULL BTREE +drop table t4, t3, t2, t1; +CREATE TABLE t1 ( +cont_nr int(11) NOT NULL auto_increment, +ver_nr int(11) NOT NULL default '0', +aufnr int(11) NOT NULL default '0', +username varchar(50) NOT NULL default '', +hdl_nr int(11) NOT NULL default '0', +eintrag date NOT NULL default '0000-00-00', +st_klasse varchar(40) NOT NULL default '', +st_wert varchar(40) NOT NULL default '', +st_zusatz varchar(40) NOT NULL default '', +st_bemerkung varchar(255) NOT NULL default '', +kunden_art varchar(40) NOT NULL default '', +mcbs_knr int(11) default NULL, +mcbs_aufnr int(11) NOT NULL default '0', +schufa_status char(1) default '?', +bemerkung text, +wirknetz text, +wf_igz int(11) NOT NULL default '0', +tarifcode varchar(80) default NULL, +recycle char(1) default NULL, +sim varchar(30) default NULL, +mcbs_tpl varchar(30) default NULL, +emp_nr int(11) NOT NULL default '0', +laufzeit int(11) default NULL, +hdl_name varchar(30) default NULL, +prov_hdl_nr int(11) NOT NULL default '0', +auto_wirknetz varchar(50) default NULL, +auto_billing varchar(50) default NULL, +touch timestamp NOT NULL, +kategorie varchar(50) default NULL, +kundentyp varchar(20) NOT NULL default '', +sammel_rech_msisdn varchar(30) NOT NULL default '', +p_nr varchar(9) NOT NULL default '', +suffix char(3) NOT NULL default '', +PRIMARY KEY (cont_nr), +KEY idx_aufnr(aufnr), +KEY idx_hdl_nr(hdl_nr), +KEY idx_st_klasse(st_klasse), +KEY ver_nr(ver_nr), +KEY eintrag_idx(eintrag), +KEY emp_nr_idx(emp_nr), +KEY wf_igz(wf_igz), +KEY touch(touch), +KEY hdl_tag(eintrag,hdl_nr), +KEY prov_hdl_nr(prov_hdl_nr), +KEY mcbs_aufnr(mcbs_aufnr), +KEY kundentyp(kundentyp), +KEY p_nr(p_nr,suffix) +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (3359356,405,3359356,'Mustermann Musterfrau',52500,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1485525,2122316,'+','','N',1909160,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',3,24,'MobilCom Shop Koeln',52500,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); +INSERT INTO t1 VALUES (3359357,468,3359357,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1503580,2139699,'+','','P',1909171,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); +INSERT INTO t1 VALUES (3359358,407,3359358,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1501358,2137473,'N','','N',1909159,'MobilComSuper92000D2',NULL,NULL,'MS9ND2',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); +INSERT INTO t1 VALUES (3359359,468,3359359,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1507831,2143894,'+','','P',1909162,'MobilComSuper9D1T10SFreisprech(Akquise)',NULL,NULL,'MS9NS1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); +INSERT INTO t1 VALUES (3359360,0,0,'Mustermann Musterfrau',29674907,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1900169997,2414578,'+',NULL,'N',1909148,'',NULL,NULL,'RV99066_2',20,NULL,'POS',29674907,NULL,NULL,20010202105916,'Mobilfunk','','','97317481','007'); +INSERT INTO t1 VALUES (3359361,406,3359361,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag storniert','','(7001-84):Storno, Kd. möchte nicht mehr','privat',NULL,0,'+','','P',1909150,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',325,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); +INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprüft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); +SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie; +Kundentyp kategorie +Privat (Private Nutzung) Mobilfunk +Warnings: +Warning 1052 Column 'kundentyp' in group statement is ambiguous +drop table t1; +SHOW STATUS LIKE 'Ssl_cipher'; +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA diff --git a/mysql-test/std_data/server-cert-des.pem b/mysql-test/std_data/server-cert-des.pem new file mode 100644 index 00000000000..3b93d865d5b --- /dev/null +++ b/mysql-test/std_data/server-cert-des.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICljCCAX4CAQEwDQYJKoZIhvcNAQEEBQAwUTELMAkGA1UEBhMCU0UxEDAOBgNV +BAgTB1VwcHNhbGExETAPBgNVBAoTCE15U1FMIEFCMRAwDgYDVQQLEwdTdXBwb3J0 +MQswCQYDVQQDEwJDQTAeFw0wNjA4MjgxMTA4NTlaFw0wOTA1MjQxMTA4NTlaMFUx +CzAJBgNVBAYTAlNFMRAwDgYDVQQIEwdVcHBzYWxhMREwDwYDVQQKEwhNeVNRTCBB +QjEQMA4GA1UECxMHU3VwcG9ydDEPMA0GA1UEAxMGc2VydmVyMIGfMA0GCSqGSIb3 +DQEBAQUAA4GNADCBiQKBgQDEiOVZcWYzZe7I8xhhUwCzvmkZifAXeMTH+8XKGLHX +NWF3FLduAmeAad9oOZgBKb+oWTdRDWXqwu6nYYUBfrUpaY27/wLkgWRgewL3LZnw +W2FjhNsjx3gI2NK+Pix47q9d+a+5T4AW5+lK499l0K0k2cvyFdIerhDW8R0t8Uru +twIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQC2LQcqLg52RbelWrKutlJ5E6rzugnJ +ZAlbN9sM98O2xFiIGDA3tb5j9LAEjE0E+RqdptEYnvy9b3szhLYXtIILZTkClf9r +Uwu1nUYPTyp+9ZYCa4fovOU5h1Ogv+9UZPds/LPDwWEn8K+lvscB4X57wJyuoEck +1Mu41OA6h77181MydSdgZo0oquJDWhdCsYHXVFVs0F6naMm2uPMCTDiQVlhHJuTO +VQMNIwxRFtvsv2tpsXsaP/8sT32d5CFebfxxSVnqQvJ4ZdIrphl6L43XU01rsEcE +K8KYujZQ6SKws+HVcGqsr7TPgJfJE6D+5RazvvIQISPvx4eduebqzqdC +-----END CERTIFICATE----- diff --git a/mysql-test/std_data/server-key-des.pem b/mysql-test/std_data/server-key-des.pem new file mode 100644 index 00000000000..b35d4ab223b --- /dev/null +++ b/mysql-test/std_data/server-key-des.pem @@ -0,0 +1,18 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: DES-EDE3-CBC,D2BE7598C7E3BDA5 + +1W3qPgw5ut80OhaAGVZZe/tfFiBAlwpX1SohdApWj+QYP+dK/mdEBhgI3BXTFNLW +pJqDTzGlKtft7hHN6QDFEdZMKxej5+2iLu14V62o+5yQgUoqswoXcmmqJCJ7AvyJ +yMBmGAzxRFlQsT8lf6o5TS1/efBvjvWhh3NG2Zq2LpyhWRRqA3kNhzktzt2WjDZe +ZkKmZJJnArr/Aw7jEBC4sH+nmgxoR18GzDddRG12hv1AWyHc3+VisTBpyNzeBy17 +rxuQtqLzkAJmId723ddw83RVNSvBUUS3G0rx5O3HPobvZK89UqVxcXtIgc11WTVU +N3DbcJq5it43Loo0W3gAngtESDm2E3rTadrmdUSDGv2wQ5dNFl6cQ1f397Sdd/WC +A0grn1tKjJ6COp80Ymdyvn+stjv/+Rl1/KHSeG0lNeZxqjPPOJ7NHaKv7qjYsJ6W +LT35/Xc3oCo5qk9FOlq/0tGjHxf6RcFr5U7k5ILKZs+RmvJ4Sv/VYShLfLTcfGbJ +wBNfRKvcHZBQJQBb1+s/kRrjFFtvhrUwLz4+c9kskp+t4qRVYywUAnGGGsMs/GPm +wYsLQZO6Bs5/taaVUyaJQW015J7FGGv+/7/A1dIhu73S/Xl/YcFbX/CMEVq2Lxxd +hZdFIuaZ7LE+0MDQWsvYMYPDPLDH11diczb/jeKBdLPOzk/FUqVx3Fin1PpcaBxY +b+7oZJhYdg/rAWDeQ/nji9qnEG8waK6x1hdkYPOrqqWQPfgM/LPsSrgWeuTSdx2B +Ixi01UlBb5UP4K7UrjyddPobmcVjXaQLNe7zaq0+OS3UnIG85GtHrQ== +-----END RSA PRIVATE KEY----- diff --git a/mysql-test/t/ssl_des-master.opt b/mysql-test/t/ssl_des-master.opt new file mode 100644 index 00000000000..b610fe3f250 --- /dev/null +++ b/mysql-test/t/ssl_des-master.opt @@ -0,0 +1 @@ +--ssl-cert=std_data/server-cert-des.pem --ssl-key=std_data/server-key-des.pem diff --git a/mysql-test/t/ssl_des.test b/mysql-test/t/ssl_des.test new file mode 100644 index 00000000000..7cf2c920ab5 --- /dev/null +++ b/mysql-test/t/ssl_des.test @@ -0,0 +1,19 @@ +# Tell the server to use a DES-encrypted cert +# then turn on ssl between the client and server +# and run a number of standard tests + +-- source include/have_openssl.inc + +# Connect by ip to avoid turning on "ssl-verify-server-cert" +connect (ssl_con,127.0.0.1,root,,,,$MASTER_MYPORT,SSL); + +# Check ssl turned on +SHOW STATUS LIKE 'Ssl_cipher'; + +# Source select test case +-- source include/common-tests.inc + +# Check ssl turned on +SHOW STATUS LIKE 'Ssl_cipher'; + + From d8d57c77b1f3490b69e0ed116a766b6434137ecd Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 28 Sep 2006 15:13:40 +0200 Subject: [PATCH 023/235] Bug#22436 Four tests require "innodb" to be configured, fail in "classic" build - Disable warnings when creating the "innodb" tables if it works anyway. - Move test that are really innodb dependent to innodb_mysql mysql-test/r/create.result: Move the innodb dependent test to innodb_mysql.test mysql-test/r/innodb_mysql.result: Move the innodb dependent test to innodb_mysql.test mysql-test/t/create.test: Move the innodb dependent test to innodb_mysql.test mysql-test/t/innodb_mysql.test: Move the innodb dependent test to innodb_mysql.test mysql-test/t/lock_multi.test: Disable warnings while creating the innodb table. If innodb is not available, the table will be created with default engine and thus create a warning. Regardless of this, test output should be the same. mysql-test/t/sp.test: Disable warnings while creating the innodb table. If innodb is not available, the table will be created with default engine and thus create a warning. Regardless of this, test output should be the same. mysql-test/t/view.test: Disable warnings while creating the innodb table. If innodb is not available, the table will be created with default engine and thus create a warning. Regardless of this, test output should be the same. --- mysql-test/r/create.result | 6 ------ mysql-test/r/innodb_mysql.result | 6 ++++++ mysql-test/t/create.test | 8 -------- mysql-test/t/innodb_mysql.test | 8 ++++++++ mysql-test/t/lock_multi.test | 3 +++ mysql-test/t/sp.test | 3 +++ mysql-test/t/view.test | 5 +++++ 7 files changed, 25 insertions(+), 14 deletions(-) diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 3f8083a0e20..1cdd1b97243 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -767,9 +767,3 @@ t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=4294967295 drop table t1; -create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb -character set utf8 collate utf8_general_ci; -Warnings: -Warning 1071 Specified key was too long; max key length is 765 bytes -insert into t1 values('aaa'); -drop table t1; diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index e7d097a1d2f..1afc1baa6e8 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -337,3 +337,9 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where DROP TABLE t1,t2; +create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb +character set utf8 collate utf8_general_ci; +Warnings: +Warning 1071 Specified key was too long; max key length is 765 bytes +insert into t1 values('aaa'); +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 07edbf206fe..61c98f5a000 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -666,12 +666,4 @@ alter table t1 max_rows=100000000000; show create table t1; drop table t1; -# -# Bug#17530: Incorrect key truncation on table creation caused server crash. -# -create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb - character set utf8 collate utf8_general_ci; -insert into t1 values('aaa'); -drop table t1; - # End of 5.0 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index 59dbe5e96d4..1a6aede599f 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -302,3 +302,11 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id WHERE t1.name LIKE 'A%' OR FALSE; DROP TABLE t1,t2; + +# +# Bug#17530: Incorrect key truncation on table creation caused server crash. +# +create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb + character set utf8 collate utf8_general_ci; +insert into t1 values('aaa'); +drop table t1; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 627c33b3d82..33e268ccb11 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -225,7 +225,10 @@ DROP TABLE t1; # Bug #17264: MySQL Server freeze # connection locker; +# Disable warnings to allow test to run also without InnoDB +--disable_warnings create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; +--enable_warnings lock tables t1 write; connection writer; --sleep 2 diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 4b0f463a9e3..7e380a25603 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -5634,7 +5634,10 @@ drop procedure bug16887| # Bug#13575 SP funcs in select with distinct/group and order by can # produce bad data # +# Disable warnings to allow test to run also without InnoDB +--disable_warnings create table t3 (f1 int, f2 varchar(3), primary key(f1)) engine=innodb| +--enable_warnings insert into t3 values (1,'aaa'),(2,'bbb'),(3,'ccc')| CREATE FUNCTION bug13575 ( p1 integer ) returns varchar(3) diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index edff38274c4..f966646710a 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1801,7 +1801,10 @@ drop table t1; # underlying tables (BUG#6443) # set sql_mode='strict_all_tables'; +# Disable warnings to allow test to run aslo without InnoDB +--disable_warnings CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB; +--enable_warnings CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1; CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2; -- error 1364 @@ -1857,7 +1860,9 @@ drop table t1; # # Test for bug #11771: wrong query_id in SELECT * FROM # +--disable_warnings CREATE TABLE t1 (f1 char) ENGINE = innodb; +--enable_warnings INSERT INTO t1 VALUES ('A'); CREATE VIEW v1 AS SELECT * FROM t1; From 31cfa6f11b5b958930f7cb3e9966098ff925cf97 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Sep 2006 11:32:40 +0200 Subject: [PATCH 024/235] Add possibility to specify which delimiter to read until in "write_file" and "perl" commands fix memory leaks reported by valgrind mysql-test/r/mysqltest.result: Update result file mysql-test/t/mysqltest.test: Add tests for specifying delimiter --- client/mysqltest.c | 74 +++++++++++++++++++++++++---------- mysql-test/r/mysqltest.result | 4 ++ mysql-test/t/mysqltest.test | 26 ++++++++++++ 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 13d5874628e..d0238fe521f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -16,12 +16,14 @@ /* mysqltest test tool * See the "MySQL Test framework manual" for more information + * http://dev.mysql.com/doc/mysqltest/en/index.html * * Written by: * Sasha Pachev * Matt Wagner * Monty * Jani + * Magnus **/ #define MTEST_VERSION "2.7" @@ -1332,6 +1334,7 @@ static void do_exec(struct st_query *query) query->first_argument, query->expected_errno[0].code.errnum); } + dynstr_free(&ds_cmd); free_replace(); DBUG_VOID_RETURN; } @@ -1757,22 +1760,32 @@ static my_bool match_delimiter(int c, const char* delim, uint length) } -static void read_until_EOF(DYNAMIC_STRING* ds) +static void read_until_delimiter(DYNAMIC_STRING *ds, + DYNAMIC_STRING *ds_delimiter) { int c; - DBUG_ENTER("read_until_EOF"); + DBUG_ENTER("read_until_delimiter"); + DBUG_PRINT("enter", ("delimiter: %s, length: %d", + ds_delimiter->str, ds_delimiter->length)); - /* Read from file until delimiter EOF is found */ + if (ds_delimiter->length > MAX_DELIMITER) + die("Max delimiter length(%d) exceeded", MAX_DELIMITER); + + /* Read from file until delimiter is found */ while (1) { c= my_getc(cur_file->file); - if (feof(cur_file->file)) - die("End of file encountered before 'EOF' delimiter was found"); + if (c == '\n') + cur_file->lineno++; - if (match_delimiter(c, "EOF", 3)) + if (feof(cur_file->file)) + die("End of file encountered before '%s' delimiter was found", + ds_delimiter->str); + + if (match_delimiter(c, ds_delimiter->str, ds_delimiter->length)) { - DBUG_PRINT("exit", ("Found EOF")); + DBUG_PRINT("exit", ("Found delimiter '%s'", ds_delimiter->str)); break; } dynstr_append_mem(ds, (const char*)&c, 1); @@ -1788,7 +1801,7 @@ static void read_until_EOF(DYNAMIC_STRING* ds) command called command DESCRIPTION - write_file ; + write_file []; <...> < what to write line n> @@ -1800,18 +1813,23 @@ static void read_until_EOF(DYNAMIC_STRING* ds) < what to write line n> EOF - Write everything between the "write_file" command and EOF to "file_name" + Write everything between the "write_file" command and 'delimiter' + to "file_name" NOTE! Overwrites existing file + Default is EOF + */ static void do_write_file(struct st_query *command) { DYNAMIC_STRING ds_content; DYNAMIC_STRING ds_filename; + DYNAMIC_STRING ds_delimiter; const struct command_arg write_file_args[] = { "filename", ARG_STRING, TRUE, &ds_filename, "File to write to", + "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" }; DBUG_ENTER("do_write_file"); @@ -1820,12 +1838,17 @@ static void do_write_file(struct st_query *command) write_file_args, sizeof(write_file_args)/sizeof(struct command_arg)); + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + init_dynamic_string(&ds_content, "", 1024, 1024); - read_until_EOF(&ds_content); + read_until_delimiter(&ds_content, &ds_delimiter); DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str)); str_to_file(ds_filename.str, ds_content.str, ds_content.length); dynstr_free(&ds_content); dynstr_free(&ds_filename); + dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; } @@ -1836,22 +1859,17 @@ static void do_write_file(struct st_query *command) command command handle DESCRIPTION - perl; + perl []; <...> EOF - Execute everything after "perl" until EOF as perl. + Execute everything after "perl" until as perl. Useful for doing more advanced things but still being able to execute it on all platforms. - The function sets delimiter to EOF and remembers that this - is a perl command by setting "perl mode". The following lines - will then be parsed as any normal query, but when searching - for command in get_query_type, this function will be called - again since "perl mode" is on and the perl script can be - executed. + Default is EOF */ static void do_perl(struct st_query *command) @@ -1860,10 +1878,23 @@ static void do_perl(struct st_query *command) char buf[FN_REFLEN]; FILE *res_file; DYNAMIC_STRING ds_script; + DYNAMIC_STRING ds_delimiter; + const struct command_arg perl_args[] = { + "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" + }; DBUG_ENTER("do_perl"); + check_command_args(command, + command->first_argument, + perl_args, + sizeof(perl_args)/sizeof(struct command_arg)); + + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + init_dynamic_string(&ds_script, "", 1024, 1024); - read_until_EOF(&ds_script); + read_until_delimiter(&ds_script, &ds_delimiter); DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); @@ -1894,6 +1925,7 @@ static void do_perl(struct st_query *command) error= pclose(res_file); handle_command_error(command, WEXITSTATUS(error)); dynstr_free(&ds_script); + dynstr_free(&ds_delimiter); DBUG_VOID_RETURN; } @@ -2693,6 +2725,7 @@ static void free_replace_regex() { if (glob_replace_regex) { + delete_dynamic(&glob_replace_regex->regex_arr); my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR)); my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) glob_replace_regex,MYF(0)); @@ -4163,7 +4196,8 @@ static int reg_replace(char** buf_p, int* buf_len_p, char *pattern, res_p += left_in_str; str_p= str_end; } - } + } + my_free((gptr)subs, MYF(0)); my_regfree(&r); *res_p= 0; *buf_p= buf; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index fdc43e8852b..67634e36ab0 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -478,3 +478,7 @@ mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' hello hello hello +mysqltest: At line 1: Max delimiter length(16) exceeded +hello +hello +End of tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 8aa85937c17..4593955ca54 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1182,6 +1182,18 @@ remove_file non_existing_file; --error 1 --exec echo "write_file filename \";" | $MYSQL_TEST 2>&1 +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +Content for test_file1 +EOF +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp END_DELIMITER; +Content for test_file1 contains EOF +END_DELIMITER +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + # ---------------------------------------------------------------------------- # test for file_exist # ---------------------------------------------------------------------------- @@ -1226,6 +1238,17 @@ remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; print "hello\n"; EOF +--perl EOF +print "hello\n"; +EOF + +--perl DELIMITER +print "hello\n"; +DELIMITER + +--error 1 +--exec echo "perl TOO_LONG_DELIMITER ;" | $MYSQL_TEST 2>&1 + perl; print "hello\n"; EOF @@ -1234,3 +1257,6 @@ perl; # Print "hello" print "hello\n"; EOF + + +--echo End of tests From 8672a81bc631194934c7f1bef6bba783971f6c01 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 29 Sep 2006 11:39:54 +0200 Subject: [PATCH 025/235] No need to spcify start_lineno in die message, that is automatic --- client/mysqltest.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 856f39b4a1c..b8a5acccd34 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2031,7 +2031,7 @@ int do_save_master_pos() if (have_ndbcluster) { ulonglong start_epoch= 0, applied_epoch= 0, - latest_epoch=0, latest_trans_epoch=0, + latest_epoch=0, latest_trans_epoch=0, latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0, latest_applied_binlog_epoch= 0; int count= 0; @@ -2072,8 +2072,8 @@ int do_save_master_pos() latest_epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_epoch_str, query); + die("result does not contain '%s' in '%s'", + latest_epoch_str, query); /* latest_trans_epoch */ while (*status && strncmp(status, latest_trans_epoch_str, sizeof(latest_trans_epoch_str)-1)) @@ -2084,10 +2084,10 @@ int do_save_master_pos() latest_trans_epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_trans_epoch_str, query); + die("result does not contain '%s' in '%s'", + latest_trans_epoch_str, query); /* latest_received_binlog_epoch */ - while (*status && + while (*status && strncmp(status, latest_received_binlog_epoch_str, sizeof(latest_received_binlog_epoch_str)-1)) status++; @@ -2097,10 +2097,10 @@ int do_save_master_pos() latest_received_binlog_epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_received_binlog_epoch_str, query); + die("result does not contain '%s' in '%s'", + latest_received_binlog_epoch_str, query); /* latest_handled_binlog */ - while (*status && + while (*status && strncmp(status, latest_handled_binlog_epoch_str, sizeof(latest_handled_binlog_epoch_str)-1)) status++; @@ -2110,10 +2110,10 @@ int do_save_master_pos() latest_handled_binlog_epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_handled_binlog_epoch_str, query); + die("result does not contain '%s' in '%s'", + latest_handled_binlog_epoch_str, query); /* latest_applied_binlog_epoch */ - while (*status && + while (*status && strncmp(status, latest_applied_binlog_epoch_str, sizeof(latest_applied_binlog_epoch_str)-1)) status++; @@ -2123,16 +2123,16 @@ int do_save_master_pos() latest_applied_binlog_epoch= strtoull(status, (char**) 0, 10); } else - die("line %u: result does not contain '%s' in '%s'", - start_lineno, latest_applied_binlog_epoch_str, query); + die("result does not contain '%s' in '%s'", + latest_applied_binlog_epoch_str, query); if (count == 0) start_epoch= latest_trans_epoch; break; } } if (!row) - die("line %u: result does not contain '%s' in '%s'", - start_lineno, binlog, query); + die("result does not contain '%s' in '%s'", + binlog, query); if (latest_applied_binlog_epoch > applied_epoch) count= 0; applied_epoch= latest_applied_binlog_epoch; From 5e71afcbe79091f9113e66e161cb15c3c35f3f67 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 2 Oct 2006 12:37:01 +0200 Subject: [PATCH 026/235] Bug#21811 Odd casting with date + INTERVAL arithmetic - Type casting was not consequent, thus when adding a DATE type with a WEEK interval the result type was DATETIME and not DATE as is the norm. - By changing the order of the date internal enumerations the deviant type casting is resolved (Item_date_add_interval::fix_length_and_dec() which determines result type for this operation assumes that addition of any interval with value <= INTERVAL_DAY to date value will result in date). There are two independant places to change: interval_names[] and interval_type. mysql-test/r/func_date_add.result: Updated result file for type casting test mysql-test/r/func_time.result: Updated result file for type casting test mysql-test/t/func_date_add.test: Added test for type casting when adding intervals to date. sql/item_timefunc.cc: Changed order of "week" key word to match the date interval enumeration. sql/item_timefunc.h: Changed the order of the enumeration to better follow interval sizes. --- mysql-test/r/func_date_add.result | 14 ++++++++++++++ mysql-test/r/func_time.result | 4 ++-- mysql-test/t/func_date_add.test | 15 ++++++++++++++- sql/item_timefunc.cc | 8 ++++++-- sql/item_timefunc.h | 19 +++++++++++-------- 5 files changed, 47 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/func_date_add.result b/mysql-test/r/func_date_add.result index 841d13a6ea6..ac5709260fd 100644 --- a/mysql-test/r/func_date_add.result +++ b/mysql-test/r/func_date_add.result @@ -71,3 +71,17 @@ NULL NULL NULL drop table t1; +End of 4.1 tests +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY; +CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY +2006-09-27 +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH; +CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH +2006-10-26 +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR; +CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR +2007-09-26 +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK; +CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK +2006-10-03 +End of 5.0 tests diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index dc6a4561531..b64d1876ed4 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -612,7 +612,7 @@ date_add(date,INTERVAL "1 1:1:1" DAY_SECOND) 2003-01-03 01:01:01 select date_add(date,INTERVAL "1" WEEK) from t1; date_add(date,INTERVAL "1" WEEK) -2003-01-09 00:00:00 +2003-01-09 select date_add(date,INTERVAL "1" QUARTER) from t1; date_add(date,INTERVAL "1" QUARTER) 2003-04-02 @@ -621,7 +621,7 @@ timestampadd(MINUTE, 1, date) 2003-01-02 00:01:00 select timestampadd(WEEK, 1, date) from t1; timestampadd(WEEK, 1, date) -2003-01-09 00:00:00 +2003-01-09 select timestampadd(SQL_TSI_SECOND, 1, date) from t1; timestampadd(SQL_TSI_SECOND, 1, date) 2003-01-02 00:00:01 diff --git a/mysql-test/t/func_date_add.test b/mysql-test/t/func_date_add.test index e01fce30577..b575eeececa 100644 --- a/mysql-test/t/func_date_add.test +++ b/mysql-test/t/func_date_add.test @@ -64,4 +64,17 @@ insert into t1 values (date_add('2000-01-04', INTERVAL NULL DAY)); select * from t1; drop table t1; -# End of 4.1 tests +--echo End of 4.1 tests + +# +# Bug#21811 +# +# Make sure we end up with an appropriate +# date format (DATE) after addition operation +# +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 DAY; +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 MONTH; +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 YEAR; +SELECT CAST('2006-09-26' AS DATE) + INTERVAL 1 WEEK; + +--echo End of 5.0 tests diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 30230005f6e..f3d7ff2dbdc 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2151,11 +2151,15 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const (date_sub_interval == other->date_sub_interval)); } +/* + 'interval_names' reflects the order of the enumeration interval_type. + See item_timefunc.h + */ static const char *interval_names[]= { - "year", "quarter", "month", "day", "hour", - "minute", "week", "second", "microsecond", + "year", "quarter", "month", "week", "day", + "hour", "minute", "second", "microsecond", "year_month", "day_hour", "day_minute", "day_second", "hour_minute", "hour_second", "minute_second", "day_microsecond", diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index d5d3efeeab4..e79c62e6ffb 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -630,18 +630,21 @@ public: }; /* - The following must be sorted so that simple intervals comes first. - (get_interval_value() depends on this) + 'interval_type' must be sorted so that simple intervals comes first, + ie year, quarter, month, week, day, hour, etc. The order based on + interval size is also important and the intervals should be kept in a + large to smaller order. (get_interval_value() depends on this) */ enum interval_type { - INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, - INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND , - INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, - INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, - INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND, - INTERVAL_MINUTE_MICROSECOND, INTERVAL_SECOND_MICROSECOND + INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, + INTERVAL_DAY, INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, + INTERVAL_MICROSECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, + INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, + INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, + INTERVAL_HOUR_MICROSECOND, INTERVAL_MINUTE_MICROSECOND, + INTERVAL_SECOND_MICROSECOND }; class Item_date_add_interval :public Item_date_func From 9368c7bcd888dde02fc3975ea7bd007417cec9ba Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 15:33:44 +0200 Subject: [PATCH 027/235] Update mysqltest to latest version - ie. backport from 5.1 - also update testcase error dected by new version mysql-test/include/show_msg.inc: BitKeeper file /home/msvensson/mysql/same_tools/my41-same_tools/mysql-test/include/show_msg.inc mysql-test/include/show_msg80.inc: BitKeeper file /home/msvensson/mysql/same_tools/my41-same_tools/mysql-test/include/show_msg80.inc BitKeeper/deleted/.del-rpl_chain_temp_table.test: Delete: mysql-test/t/rpl_chain_temp_table.test BitKeeper/deleted/.del-rpl_chain_temp_table.result: Delete: mysql-test/r/rpl_chain_temp_table.result BitKeeper/deleted/.del-rpl_failsafe.result: Delete: mysql-test/r/rpl_failsafe.result BitKeeper/deleted/.del-rpl_failsafe.test: Delete: mysql-test/t/rpl_failsafe.test BitKeeper/deleted/.del-rpl_heap.test: Delete: mysql-test/t/rpl_heap.test BitKeeper/deleted/.del-rpl_heap.result: Delete: mysql-test/r/rpl_heap.result BitKeeper/deleted/.del-rpl000018.result: Delete: mysql-test/r/rpl000018.result BitKeeper/deleted/.del-rpl000018.test: Delete: mysql-test/t/rpl000018.test client/Makefile.am: Link mysqltest with mysys/my_copy.c client/mysqltest.c: Update mysqltest to latest version mysql-test/include/have_multi_ndb.inc: Remove old syntax "@filename" in favor of "--require filename" mysql-test/include/master-slave.inc: Remove old syntax "@filename" in favor of "--require filename" mysql-test/include/ps_query.inc: Remove the comment about no output now when it does. mysql-test/r/check.result: Update output from --send mysql-test/r/connect.result: Update result file for connect test after backport form 5.1 mysql-test/r/flush.result: Update output from --send mysql-test/r/flush_block_commit.result: Update output from --send mysql-test/r/func_misc.result: Update output from --send mysql-test/r/grant2.result: Update output from --send mysql-test/r/handler.result: Update output from --send mysql-test/r/kill.result: Update output from --send mysql-test/r/lock_multi.result: Update output from --send mysql-test/r/mix_innodb_myisam_binlog.result: Update output from --send mysql-test/r/mysqltest.result: Update mysqltest.result after backport mysql-test/r/ps_2myisam.result: Update result as the output from query is now printed mysql-test/r/ps_3innodb.result: Update result as the output from query is now printed mysql-test/r/ps_4heap.result: Update result as the output from query is now printed mysql-test/r/ps_5merge.result: Update result as the output from query is now printed mysql-test/r/ps_6bdb.result: Update result as the output from query is now printed mysql-test/r/ps_7ndb.result: Update result as the output from query is now printed mysql-test/r/rename.result: Update output from --send mysql-test/r/rpl000001.result: Update output from --send mysql-test/r/rpl_error_ignored_table.result: Update output from --send mysql-test/r/rpl_master_pos_wait.result: Update output from --send mysql-test/r/subselect.result: Update result file after adding missing ; mysql-test/r/synchronization.result: Update output from --send mysql-test/r/type_blob.result: Update result file after adding missing ; mysql-test/t/connect.test: Backport test from 5.1 mysql-test/t/init_file.test: Update test so something is printed mysql-test/t/mysql_client_test.test: Update test so result is sent to file and something is printed mysql-test/t/mysqltest.test: Backport latest mysqltest.test file mysql-test/t/ps.test: Move the --replace_column statement to just before the statetement it should replace mysql-test/t/ps_1general.test: Move the --replace_column statement to just before the statetement it should replace mysql-test/t/ps_grant.test: Remove the $DB, no other test uses it mysql-test/t/rpl_flush_tables.test: Fetch $SERVER_VERSION from the db server mysql-test/t/rpl_trunc_temp.test: Remove the selection of connection master after it's been disconnected already mysql-test/t/subselect.test: Add missing ; mysql-test/t/type_blob.test: Add missing ; --- client/Makefile.am | 4 +- client/mysqltest.c | 7702 +++++++++++------- mysql-test/include/have_multi_ndb.inc | 12 +- mysql-test/include/master-slave.inc | 6 +- mysql-test/include/ps_query.inc | 1 - mysql-test/include/show_msg.inc | 25 + mysql-test/include/show_msg80.inc | 118 + mysql-test/r/check.result | 2 +- mysql-test/r/connect.result | 20 + mysql-test/r/flush.result | 4 +- mysql-test/r/flush_block_commit.result | 6 +- mysql-test/r/func_misc.result | 2 +- mysql-test/r/grant2.result | 8 +- mysql-test/r/handler.result | 2 +- mysql-test/r/kill.result | 2 +- mysql-test/r/lock_multi.result | 12 +- mysql-test/r/mix_innodb_myisam_binlog.result | 2 +- mysql-test/r/mysqltest.result | 194 +- mysql-test/r/ps_2myisam.result | 2 + mysql-test/r/ps_3innodb.result | 2 + mysql-test/r/ps_4heap.result | 2 + mysql-test/r/ps_5merge.result | 4 + mysql-test/r/ps_6bdb.result | 2 + mysql-test/r/ps_7ndb.result | 2 + mysql-test/r/rename.result | 2 +- mysql-test/r/rpl000001.result | 2 +- mysql-test/r/rpl000018.result | 14 - mysql-test/r/rpl_chain_temp_table.result | 30 - mysql-test/r/rpl_error_ignored_table.result | 2 +- mysql-test/r/rpl_failsafe.result | 34 - mysql-test/r/rpl_heap.result | 29 - mysql-test/r/rpl_master_pos_wait.result | 2 +- mysql-test/r/subselect.result | 3 +- mysql-test/r/synchronization.result | 40 +- mysql-test/r/type_blob.result | 3 +- mysql-test/t/connect.test | 83 +- mysql-test/t/init_file.test | 5 +- mysql-test/t/mysql_client_test.test | 6 +- mysql-test/t/mysqltest.test | 745 +- mysql-test/t/ps.test | 6 +- mysql-test/t/ps_1general.test | 2 +- mysql-test/t/ps_grant.test | 2 +- mysql-test/t/rpl000018.test | 29 - mysql-test/t/rpl_chain_temp_table.test | 101 - mysql-test/t/rpl_failsafe.test | 24 - mysql-test/t/rpl_flush_tables.test | 2 + mysql-test/t/rpl_heap.test | 51 - mysql-test/t/rpl_trunc_temp.test | 3 - mysql-test/t/subselect.test | 2 +- mysql-test/t/type_blob.test | 2 +- 50 files changed, 6023 insertions(+), 3337 deletions(-) create mode 100755 mysql-test/include/show_msg.inc create mode 100755 mysql-test/include/show_msg80.inc delete mode 100644 mysql-test/r/rpl000018.result delete mode 100644 mysql-test/r/rpl_chain_temp_table.result delete mode 100644 mysql-test/r/rpl_failsafe.result delete mode 100644 mysql-test/r/rpl_heap.result delete mode 100644 mysql-test/t/rpl000018.test delete mode 100644 mysql-test/t/rpl_chain_temp_table.test delete mode 100644 mysql-test/t/rpl_failsafe.test delete mode 100644 mysql-test/t/rpl_heap.test diff --git a/client/Makefile.am b/client/Makefile.am index c0569d5fa6f..fe150defe03 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -30,7 +30,9 @@ mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysqladmin_SOURCES = mysqladmin.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS) -mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c +mysqltest_SOURCES= mysqltest.c \ + $(top_srcdir)/mysys/my_getsystime.c \ + $(top_srcdir)/mysys/my_copy.c mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) mysqlbinlog_SOURCES = mysqlbinlog.cc ../mysys/mf_tempdir.c mysqlmanagerc_SOURCES = mysqlmanagerc.c diff --git a/client/mysqltest.c b/client/mysqltest.c index ad0f9f857bb..623c33d0f4f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -14,35 +14,22 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* mysqltest test tool - * See the manual for more information - * TODO: document better how mysqltest works - * - * Written by: - * Sasha Pachev - * Matt Wagner - * Monty - * Jani - **/ +/* + mysqltest -/********************************************************************** - TODO: + Tool used for executing a .test file -- Do comparison line by line, instead of doing a full comparison of - the text file. This will save space as we don't need to keep many - results in memory. It will also make it possible to do simple - 'comparison' fixes like accepting the result even if a float differed - in the last decimals. + See the "MySQL Test framework manual" for more information + http://dev.mysql.com/doc/mysqltest/en/index.html -- Don't buffer lines from the test that you don't expect to need - again. + Written by: + Sasha Pachev + Matt Wagner + Monty + Jani +*/ -- Change 'read_line' to be faster by using the readline.cc code; - We can do better than calling feof() for each character! - -**********************************************************************/ - -#define MTEST_VERSION "2.5" +#define MTEST_VERSION "3.0" #include #include @@ -51,18 +38,18 @@ #include #include #include +#include #include #include -#include /* Error codes */ #include #include #include -#include #include -#include "my_regex.h" /* Our own version of lib */ +#include "my_regex.h" /* Our own version of regex */ #ifdef HAVE_SYS_WAIT_H #include #endif + #ifndef WEXITSTATUS # ifdef __WIN__ # define WEXITSTATUS(stat_val) (stat_val) @@ -70,166 +57,144 @@ # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) # endif #endif -#define MAX_QUERY 131072 -#define MAX_VAR_NAME 256 -#define MAX_COLUMNS 256 -#define PAD_SIZE 128 -#define MAX_CONS 128 -#define MAX_INCLUDE_DEPTH 16 -#define LAZY_GUESS_BUF_SIZE 8192 -#define INIT_Q_LINES 1024 -#define MIN_VAR_ALLOC 32 -#define BLOCK_STACK_DEPTH 32 -#define MAX_EXPECTED_ERRORS 10 -#define QUERY_SEND 1 -#define QUERY_REAP 2 -#ifndef MYSQL_MANAGER_PORT -#define MYSQL_MANAGER_PORT 23546 -#endif -#define MAX_SERVER_ARGS 64 -/* - Sometimes in a test the client starts before - the server - to solve the problem, we try again - after some sleep if connection fails the first - time -*/ -#define CON_RETRY_SLEEP 2 -#define MAX_CON_TRIES 5 +#define MAX_VAR_NAME_LENGTH 256 +#define MAX_COLUMNS 256 +#define MAX_EMBEDDED_SERVER_ARGS 64 +#define MAX_DELIMITER_LENGTH 16 -#define SLAVE_POLL_INTERVAL 300000 /* 0.3 of a sec */ -#define DEFAULT_DELIMITER ";" -#define MAX_DELIMITER 16 +/* Flags controlling send and reap */ +#define QUERY_SEND_FLAG 1 +#define QUERY_REAP_FLAG 2 -#define RESULT_OK 0 -#define RESULT_CONTENT_MISMATCH 1 -#define RESULT_LENGTH_MISMATCH 2 + enum { + RESULT_OK= 0, + RESULT_CONTENT_MISMATCH= 1, + RESULT_LENGTH_MISMATCH= 2 + }; -enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, - OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC, - OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, - OPT_SSL_CIPHER,OPT_PS_PROTOCOL}; - -/* ************************************************************************ */ -/* - The list of error codes to --error are stored in an internal array of - structs. This struct can hold numeric SQL error codes or SQLSTATE codes - as strings. The element next to the last active element in the list is - set to type ERR_EMPTY. When an SQL statement returns an error, we use - this list to check if this is an expected error. -*/ - -enum match_err_type -{ - ERR_EMPTY= 0, - ERR_ERRNO, - ERR_SQLSTATE +enum { + OPT_SKIP_SAFEMALLOC=256, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, + OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_CIPHER, OPT_PS_PROTOCOL, + OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, + OPT_SSL_VERIFY_SERVER_CERT, OPT_MAX_CONNECT_RETRIES, + OPT_MARK_PROGRESS }; -typedef struct -{ - enum match_err_type type; - union - { - uint errnum; - char sqlstate[SQLSTATE_LENGTH+1]; /* \0 terminated string */ - } code; -} match_err; - -static match_err global_expected_errno[MAX_EXPECTED_ERRORS]; -static uint global_expected_errors; - -/* ************************************************************************ */ - -static int record = 0, opt_sleep=0; -static char *db = 0, *pass=0; -const char *user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./"; -static int port = 0; -static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0; -static my_bool tty_password= 0, ps_protocol= 0, ps_protocol_enabled= 0; -static uint start_lineno= 0, *lineno; -const char *manager_user="root",*manager_host=0; -char *manager_pass=0; -int manager_port=MYSQL_MANAGER_PORT; -int manager_wait_timeout=3; -MYSQL_MANAGER* manager=0; +static int record= 0, opt_sleep= -1; +static char *db= 0, *pass= 0; +const char *user= 0, *host= 0, *unix_sock= 0, *opt_basedir= "./"; +const char *opt_include= 0; +static int port= 0; +static int opt_max_connect_retries; +static my_bool opt_compress= 0, silent= 0, verbose= 0; +static my_bool tty_password= 0; +static my_bool opt_mark_progress= 0; +static my_bool ps_protocol= 0, ps_protocol_enabled= 0; +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, display_metadata= FALSE; +static my_bool disable_query_log= 0, disable_result_log= 0; +static my_bool disable_warnings= 0, disable_ps_warnings= 0; +static my_bool disable_info= 1; +static my_bool abort_on_error= 1; static char **default_argv; -static const char *load_default_groups[]= { "mysqltest","client",0 }; -static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer; +static const char *load_default_groups[]= { "mysqltest", "client", 0 }; +static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; -typedef struct +static uint start_lineno= 0; /* Start line of current command */ + +static char delimiter[MAX_DELIMITER_LENGTH]= ";"; +static uint delimiter_length= 1; + +static char TMPDIR[FN_REFLEN]; + +/* Block stack */ +enum block_cmd { + cmd_none, + cmd_if, + cmd_while +}; + +struct st_block +{ + int line; /* Start line of block */ + my_bool ok; /* Should block be executed */ + enum block_cmd cmd; /* Command owning the block */ +}; + +static struct st_block block_stack[32]; +static struct st_block *cur_block, *block_stack_end; + +/* Open file stack */ +struct st_test_file { FILE* file; const char *file_name; -} test_file; + uint lineno; /* Current line in file */ +}; -static test_file file_stack[MAX_INCLUDE_DEPTH]; -static test_file* cur_file; -static test_file* file_stack_end; +static struct st_test_file file_stack[16]; +static struct st_test_file* cur_file; +static struct st_test_file* file_stack_end; -static uint lineno_stack[MAX_INCLUDE_DEPTH]; -static char TMPDIR[FN_REFLEN]; -static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER; -static uint delimiter_length= 1; static CHARSET_INFO *charset_info= &my_charset_latin1; /* Default charset */ static const char *charset_name= "latin1"; /* Default character set name */ -static int embedded_server_arg_count=0; -static char *embedded_server_args[MAX_SERVER_ARGS]; - -static my_bool display_result_vertically= FALSE, display_metadata= FALSE; - -/* See the timer_output() definition for details */ -static char *timer_file = NULL; -static ulonglong timer_start; -static int got_end_timer= FALSE; -static void timer_output(void); -static ulonglong timer_now(void); - -static my_regex_t ps_re; /* Holds precompiled re for valid PS statements */ -static void ps_init_re(void); -static int ps_match_re(char *); -static char *ps_eprint(int); -static void ps_free_reg(void); - -static const char *embedded_server_groups[] = { +static const char *embedded_server_groups[]= +{ "server", "embedded", "mysqltest_SERVER", NullS }; +static int embedded_server_arg_count=0; +static char *embedded_server_args[MAX_EMBEDDED_SERVER_ARGS]; + +/* + Timer related variables + See the timer_output() definition for details +*/ +static char *timer_file = NULL; +static ulonglong timer_start; +static void timer_output(void); +static ulonglong timer_now(void); + +static ulonglong progress_start= 0; + +/* Precompiled re's */ +static my_regex_t ps_re; /* the query can be run using PS protocol */ +static my_regex_t sp_re; /* the query can be run as a SP */ +static my_regex_t view_re; /* the query can be run as a view*/ + +static void init_re(void); +static int match_re(my_regex_t *, char *); +static void free_re(void); + DYNAMIC_ARRAY q_lines; #include "sslopt-vars.h" -typedef struct +struct +{ + int read_lines,current_line; +} parser; + +struct { char file[FN_REFLEN]; ulong pos; -} MASTER_POS ; +} master_pos; -struct connection -{ - MYSQL mysql; - char *name; -}; - -typedef struct -{ - int read_lines,current_line; -} PARSER; - -MYSQL_RES *last_result=0; - -PARSER parser; -MASTER_POS master_pos; /* if set, all results are concated and compared against this file */ -const char *result_file = 0; +const char *result_file= 0; -typedef struct +typedef struct st_var { char *name; int name_len; @@ -239,81 +204,71 @@ typedef struct int alloced_len; int int_dirty; /* do not update string if int is updated until first read */ int alloced; + char *env_s; } VAR; -#if defined(__NETWARE__) || defined(__WIN__) -/* - Netware doesn't proved environment variable substitution that is done - by the shell in unix environments. We do this in the following function: -*/ - -static char *subst_env_var(const char *cmd); -static FILE *my_popen(const char *cmd, const char *mode); -#define popen(A,B) my_popen((A),(B)) -#endif /* __NETWARE__ */ - -VAR var_reg[10]; /*Perl/shell-like variable registers */ +VAR var_reg[10]; + HASH var_hash; -my_bool disable_query_log=0, disable_result_log=0, disable_warnings=0; -my_bool disable_info= 1; /* By default off */ -my_bool abort_on_error= 1; -struct connection cons[MAX_CONS]; -struct connection* cur_con, *next_con, *cons_end; - - /* Add new commands before Q_UNKNOWN !*/ - -enum enum_commands { -Q_CONNECTION=1, Q_QUERY, -Q_CONNECT, Q_SLEEP, Q_REAL_SLEEP, -Q_INC, Q_DEC, -Q_SOURCE, Q_DISCONNECT, -Q_LET, Q_ECHO, -Q_WHILE, Q_END_BLOCK, -Q_SYSTEM, Q_RESULT, -Q_REQUIRE, Q_SAVE_MASTER_POS, -Q_SYNC_WITH_MASTER, -Q_SYNC_SLAVE_WITH_MASTER, -Q_ERROR, -Q_SEND, Q_REAP, -Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, -Q_PING, Q_EVAL, -Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, -Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, -Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, -Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, -Q_SERVER_START, Q_SERVER_STOP,Q_REQUIRE_MANAGER, -Q_WAIT_FOR_SLAVE_TO_STOP, -Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, -Q_ENABLE_INFO, Q_DISABLE_INFO, -Q_ENABLE_METADATA, Q_DISABLE_METADATA, -Q_EXEC, Q_DELIMITER, -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_START_TIMER, Q_END_TIMER, -Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, -Q_EXIT, -Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, -Q_IF, - -Q_UNKNOWN, /* Unknown command. */ -Q_COMMENT, /* Comments, ignored. */ -Q_COMMENT_WITH_COMMAND -}; - -/* this should really be called command */ -struct st_query +struct st_connection { - char *query, *query_buf,*first_argument,*last_argument,*end; - int first_word_len; - my_bool abort_on_error, require_file; - match_err expected_errno[MAX_EXPECTED_ERRORS]; - uint expected_errors; - char record_file[FN_REFLEN]; - enum enum_commands type; + MYSQL mysql; + /* Used when creating views and sp, to avoid implicit commit */ + MYSQL* util_mysql; + char *name; + MYSQL_STMT* stmt; }; +struct st_connection connections[128]; +struct st_connection* cur_con, *next_con, *connections_end; + +/* + List of commands in mysqltest + Must match the "command_names" array + Add new commands before Q_UNKNOWN! +*/ +enum enum_commands { + Q_CONNECTION=1, Q_QUERY, + Q_CONNECT, Q_SLEEP, Q_REAL_SLEEP, + Q_INC, Q_DEC, + Q_SOURCE, Q_DISCONNECT, + Q_LET, Q_ECHO, + Q_WHILE, Q_END_BLOCK, + Q_SYSTEM, Q_RESULT, + Q_REQUIRE, Q_SAVE_MASTER_POS, + Q_SYNC_WITH_MASTER, + Q_SYNC_SLAVE_WITH_MASTER, + Q_ERROR, + Q_SEND, Q_REAP, + Q_DIRTY_CLOSE, Q_REPLACE, Q_REPLACE_COLUMN, + Q_PING, Q_EVAL, + Q_RPL_PROBE, Q_ENABLE_RPL_PARSE, + Q_DISABLE_RPL_PARSE, Q_EVAL_RESULT, + Q_ENABLE_QUERY_LOG, Q_DISABLE_QUERY_LOG, + Q_ENABLE_RESULT_LOG, Q_DISABLE_RESULT_LOG, + Q_WAIT_FOR_SLAVE_TO_STOP, + Q_ENABLE_WARNINGS, Q_DISABLE_WARNINGS, + Q_ENABLE_PS_WARNINGS, Q_DISABLE_PS_WARNINGS, + Q_ENABLE_INFO, Q_DISABLE_INFO, + Q_ENABLE_METADATA, Q_DISABLE_METADATA, + Q_EXEC, Q_DELIMITER, + 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_START_TIMER, Q_END_TIMER, + Q_CHARACTER_SET, Q_DISABLE_PS_PROTOCOL, Q_ENABLE_PS_PROTOCOL, + Q_DISABLE_RECONNECT, Q_ENABLE_RECONNECT, + Q_IF, + Q_DISABLE_PARSING, Q_ENABLE_PARSING, + Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, + Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, + + Q_UNKNOWN, /* Unknown command. */ + Q_COMMENT, /* Comments, ignored. */ + Q_COMMENT_WITH_COMMAND +}; + const char *command_names[]= { @@ -348,16 +303,17 @@ const char *command_names[]= "enable_rpl_parse", "disable_rpl_parse", "eval_result", + /* Enable/disable that the _query_ is logged to result file */ "enable_query_log", "disable_query_log", + /* Enable/disable that the _result_ from a query is logged to result file */ "enable_result_log", "disable_result_log", - "server_start", - "server_stop", - "require_manager", "wait_for_slave_to_stop", "enable_warnings", "disable_warnings", + "enable_ps_warnings", + "disable_ps_warnings", "enable_info", "disable_info", "enable_metadata", @@ -375,80 +331,118 @@ const char *command_names[]= "character_set", "disable_ps_protocol", "enable_ps_protocol", - "exit", "disable_reconnect", "enable_reconnect", "if", + "disable_parsing", + "enable_parsing", + "replace_regex", + "remove_file", + "file_exists", + "write_file", + "copy_file", + "perl", + "die", 0 }; -/* Block stack */ -typedef struct + +/* + The list of error codes to --error are stored in an internal array of + structs. This struct can hold numeric SQL error codes, error names or + SQLSTATE codes as strings. The element next to the last active element + in the list is set to type ERR_EMPTY. When an SQL statement returns an + error, we use this list to check if this is an expected error. +*/ +enum match_err_type { - int line; /* Start line of block */ - my_bool ok; /* Should block be executed */ - enum enum_commands cmd; /* Command owning the block */ -} BLOCK; -static BLOCK block_stack[BLOCK_STACK_DEPTH]; -static BLOCK *cur_block, *block_stack_end; + ERR_EMPTY= 0, + ERR_ERRNO, + ERR_SQLSTATE +}; + +struct st_match_err +{ + enum match_err_type type; + union + { + uint errnum; + char sqlstate[SQLSTATE_LENGTH+1]; /* \0 terminated string */ + } code; +}; + +struct st_expected_errors +{ + struct st_match_err err[10]; + uint count; +}; +static struct st_expected_errors saved_expected_errors; + +struct st_command +{ + char *query, *query_buf,*first_argument,*last_argument,*end; + int first_word_len, query_len; + my_bool abort_on_error, require_file; + struct st_expected_errors expected_errors; + char record_file[FN_REFLEN]; + enum enum_commands type; +}; TYPELIB command_typelib= {array_elements(command_names),"", command_names, 0}; -DYNAMIC_STRING ds_res; -static void die(const char *fmt, ...); -static void init_var_hash(); -static VAR* var_from_env(const char *, const char *); -static byte* get_var_key(const byte* rec, uint* len, my_bool t); -static VAR* var_init(VAR* v, const char *name, int name_len, const char *val, - int val_len); +DYNAMIC_STRING ds_res, ds_progress; -static void var_free(void* v); +void die(const char *fmt, ...) + /* ATTRIBUTE_FORMAT(printf, 1, 2) */; +void abort_not_supported_test(const char *fmt, ...) + /* ATTRIBUTE_FORMAT(printf, 1, 2) */; +void verbose_msg(const char *fmt, ...) + /* ATTRIBUTE_FORMAT(printf, 1, 2) */; -int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname); -void reject_dump(const char *record_file, char *buf, int size); +VAR* var_from_env(const char *, const char *); +VAR* var_init(VAR* v, const char *name, int name_len, const char *val, + int val_len); +void var_free(void* v); +VAR* var_get(const char *var_name, const char** var_name_end, + my_bool raw, my_bool ignore_not_existing); +void eval_expr(VAR* v, const char *p, const char** p_end); +my_bool match_delimiter(int c, const char *delim, uint length); +void dump_result_to_reject_file(const char *record_file, char *buf, int size); +void dump_result_to_log_file(const char *record_file, char *buf, int size); -int close_connection(struct st_query*); -static void set_charset(struct st_query*); -VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, - my_bool ignore_not_existing); -int eval_expr(VAR* v, const char *p, const char** p_end); -static int read_server_arguments(const char *name); - -/* Definitions for replace result */ - -typedef struct st_pointer_array { /* when using array-strings */ - TYPELIB typelib; /* Pointer to strings */ - byte *str; /* Strings is here */ - int7 *flag; /* Flag about each var. */ - uint array_allocs,max_count,length,max_length; -} POINTER_ARRAY; - -struct st_replace; -struct st_replace *init_replace(my_string *from, my_string *to, uint count, - my_string word_end_chars); -uint replace_strings(struct st_replace *rep, my_string *start, - uint *max_length, const char *from); -void free_replace(); -static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name); -void free_pointer_array(POINTER_ARRAY *pa); -static int initialize_replace_buffer(void); -static void free_replace_buffer(void); -static void do_eval(DYNAMIC_STRING *query_eval, const char *query); +void do_eval(DYNAMIC_STRING *query_eval, const char *query, + const char *query_end, my_bool pass_through_escape_chars); void str_to_file(const char *fname, char *str, int size); -int do_server_op(struct st_query *q,const char *op); -struct st_replace *glob_replace; -static char *out_buff; -static uint out_length; +#ifdef __WIN__ +void free_tmp_sh_file(); +void free_win_path_patterns(); +#endif + static int eval_result = 0; -/* For column replace */ -char *replace_column[MAX_COLUMNS]; -uint max_replace_column= 0; +/* For replace_column */ +static char *replace_column[MAX_COLUMNS]; +static uint max_replace_column= 0; +void do_get_replace_column(struct st_command*); +void free_replace_column(); + +/* For replace */ +void do_get_replace(struct st_command *command); +void free_replace(); + +/* For replace_regex */ +void do_get_replace_regex(struct st_command *command); +void free_replace_regex(); + + +void free_all_replace(){ + free_replace(); + free_replace_regex(); + free_replace_column(); +} -static void get_replace_column(struct st_query *q); -static void free_replace_column(); /* Disable functions that only exist in MySQL 4.0 */ #if MYSQL_VERSION_ID < 40000 @@ -457,42 +451,64 @@ void mysql_disable_rpl_parse(MYSQL* mysql __attribute__((unused))) {} int mysql_rpl_parse_enabled(MYSQL* mysql __attribute__((unused))) { return 1; } my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } #endif -static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, - int len); -static int handle_no_error(struct st_query *q); -static void do_eval(DYNAMIC_STRING* query_eval, const char *query) +void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, + int len); +void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); +void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val); + +void handle_error(struct st_command*, + unsigned int err_errno, const char *err_error, + const char *err_sqlstate, DYNAMIC_STRING *ds); +void handle_no_error(struct st_command*); + + + +void do_eval(DYNAMIC_STRING *query_eval, const char *query, + const char *query_end, my_bool pass_through_escape_chars) { const char *p; - register char c; + register char c, next_c; register int escaped = 0; - VAR* v; + VAR *v; DBUG_ENTER("do_eval"); - for (p= query; (c = *p); ++p) + for (p= query; (c= *p) && p < query_end; ++p) { switch(c) { case '$': if (escaped) { - escaped = 0; + escaped= 0; dynstr_append_mem(query_eval, p, 1); } else { - if (!(v = var_get(p, &p, 0, 0))) + if (!(v= var_get(p, &p, 0, 0))) die("Bad variable in eval"); dynstr_append_mem(query_eval, v->str_val, v->str_val_len); } break; case '\\': + next_c= *(p+1); if (escaped) { - escaped = 0; + escaped= 0; dynstr_append_mem(query_eval, p, 1); } + else if (next_c == '\\' || next_c == '$' || next_c == '"') + { + /* Set escaped only if next char is \, " or $ */ + escaped= 1; + + if (pass_through_escape_chars) + { + /* The escape char should be added to the output string. */ + dynstr_append_mem(query_eval, p, 1); + } + } else - escaped = 1; + dynstr_append_mem(query_eval, p, 1); break; default: dynstr_append_mem(query_eval, p, 1); @@ -503,24 +519,148 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query) } -static void close_cons() +enum arg_type { - DBUG_ENTER("close_cons"); - if (last_result) - mysql_free_result(last_result); - for (--next_con; next_con >= cons; --next_con) + ARG_STRING, + ARG_REST +}; + +struct command_arg { + const char *argname; /* Name of argument */ + enum arg_type type; /* Type of argument */ + my_bool required; /* Argument required */ + DYNAMIC_STRING *ds; /* Storage for argument */ + const char *description; /* Description of the argument */ +}; + + +void check_command_args(struct st_command *command, + const char *arguments, + const struct command_arg *args, + int num_args, const char delimiter_arg) +{ + int i; + const char *ptr= arguments; + const char *start; + + DBUG_ENTER("check_command_args"); + DBUG_PRINT("enter", ("num_args: %d", num_args)); + for (i= 0; i < num_args; i++) { + const struct command_arg *arg= &args[i]; + + switch (arg->type) + { + /* A string */ + case ARG_STRING: + /* Skip leading spaces */ + while (*ptr && *ptr == ' ') + ptr++; + start= ptr; + /* Find end of arg, terminated by "delimiter_arg" */ + while (*ptr && *ptr != delimiter_arg) + ptr++; + if (ptr > start) + { + init_dynamic_string(arg->ds, 0, ptr-start, 32); + do_eval(arg->ds, start, ptr, FALSE); + } + else + { + /* Empty string */ + init_dynamic_string(arg->ds, "", 0, 0); + } + command->last_argument= (char*)ptr; + + /* Step past the delimiter */ + if (*ptr && *ptr == delimiter_arg) + ptr++; + DBUG_PRINT("info", ("val: %s", arg->ds->str)); + break; + + /* Rest of line */ + case ARG_REST: + start= ptr; + init_dynamic_string(arg->ds, 0, command->query_len, 256); + do_eval(arg->ds, start, command->end, FALSE); + command->last_argument= command->end; + DBUG_PRINT("info", ("val: %s", arg->ds->str)); + break; + + default: + DBUG_ASSERT("Unknown argument type"); + break; + } + + /* Check required arg */ + if (arg->ds->length == 0 && arg->required) + die("Missing required argument '%s' to command '%.*s'", arg->argname, + command->first_word_len, command->query); + + } + DBUG_VOID_RETURN; +} + + +void handle_command_error(struct st_command *command, uint error) +{ + DBUG_ENTER("handle_command_error"); + DBUG_PRINT("enter", ("error: %d", error)); + if (error != 0) + { + uint i; + + if (command->abort_on_error) + die("command \"%.*s\" failed with error %d", + command->first_word_len, command->query, error); + for (i= 0; i < command->expected_errors.count; i++) + { + DBUG_PRINT("info", ("expected error: %d", + command->expected_errors.err[i].code.errnum)); + if ((command->expected_errors.err[i].type == ERR_ERRNO) && + (command->expected_errors.err[i].code.errnum == error)) + { + DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %d", + command->first_word_len, command->query, error)); + DBUG_VOID_RETURN; + } + } + die("command \"%.*s\" failed with wrong error: %d", + command->first_word_len, command->query, error); + } + else if (command->expected_errors.err[0].type == ERR_ERRNO && + command->expected_errors.err[0].code.errnum != 0) + { + /* Error code we wanted was != 0, i.e. not an expected success */ + die("command \"%.*s\" succeeded - should have failed with errno %d...", + command->first_word_len, command->query, + command->expected_errors.err[0].code.errnum); + } + DBUG_VOID_RETURN; +} + + +void close_connections() +{ + DBUG_ENTER("close_connections"); + for (--next_con; next_con >= connections; --next_con) + { + if (next_con->stmt) + mysql_stmt_close(next_con->stmt); + next_con->stmt= 0; mysql_close(&next_con->mysql); + if (next_con->util_mysql) + mysql_close(next_con->util_mysql); my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); } DBUG_VOID_RETURN; } -static void close_files() +void close_files() { DBUG_ENTER("close_files"); - for (; cur_file != (file_stack-1) ; cur_file--) + for (; cur_file >= file_stack; cur_file--) { DBUG_PRINT("info", ("file_name: %s", cur_file->file_name)); if (cur_file->file && cur_file->file != stdin) @@ -532,25 +672,22 @@ static void close_files() } -static void free_used_memory() +void free_used_memory() { uint i; DBUG_ENTER("free_used_memory"); -#ifndef EMBEDDED_LIBRARY - if (manager) - mysql_manager_close(manager); -#endif - close_cons(); + + close_connections(); close_files(); hash_free(&var_hash); - for (i=0 ; i < q_lines.elements ; i++) + for (i= 0 ; i < q_lines.elements ; i++) { - struct st_query **q= dynamic_element(&q_lines, i, struct st_query**); + struct st_command **q= dynamic_element(&q_lines, i, struct st_command**); my_free((gptr) (*q)->query_buf,MYF(MY_ALLOW_ZERO_PTR)); my_free((gptr) (*q),MYF(0)); } - for (i=0; i < 10; i++) + for (i= 0; i < 10; i++) { if (var_reg[i].alloced_len) my_free(var_reg[i].str_val, MYF(MY_WME)); @@ -559,23 +696,35 @@ static void free_used_memory() my_free(embedded_server_args[--embedded_server_arg_count],MYF(0)); delete_dynamic(&q_lines); dynstr_free(&ds_res); - free_replace(); - free_replace_column(); + dynstr_free(&ds_progress); + free_all_replace(); my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); mysql_server_end(); - if (ps_protocol) - ps_free_reg(); + free_re(); +#ifdef __WIN__ + free_tmp_sh_file(); + free_win_path_patterns(); +#endif DBUG_VOID_RETURN; } -static void die(const char *fmt, ...) + +void die(const char *fmt, ...) { va_list args; DBUG_ENTER("die"); + DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); + + /* Print the error message */ va_start(args, fmt); if (fmt) { +#ifdef DBUG_ON + char buff[256]; + vsnprintf(buff, sizeof(buff), fmt, args); + DBUG_PRINT("error", ("%s", buff)); +#endif fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) fprintf(stderr, "In included file \"%s\": ", @@ -587,25 +736,69 @@ static void die(const char *fmt, ...) fflush(stderr); } va_end(args); + + /* Dump the result that has been accumulated so far to .log file */ + if (result_file && ds_res.length) + dump_result_to_log_file(result_file, ds_res.str, ds_res.length); + + /* Clean up and exit */ free_used_memory(); my_end(MY_CHECK_ERROR); + + if (!silent) + printf("not ok\n"); + exit(1); } -/* Note that we will get some memory leaks when calling this! */ -static void abort_not_supported_test() +void abort_not_supported_test(const char *fmt, ...) { + va_list args; + struct st_test_file* err_file= cur_file; DBUG_ENTER("abort_not_supported_test"); - fprintf(stderr, "This test is not supported by this installation\n"); - if (!silent) - printf("skipped\n"); + + /* Print include filestack */ + fprintf(stderr, "The test '%s' is not supported by this installation\n", + file_stack->file_name); + fprintf(stderr, "Detected in file %s at line %d\n", + err_file->file_name, err_file->lineno); + while (err_file != file_stack) + { + err_file--; + fprintf(stderr, "included from %s at line %d\n", + err_file->file_name, err_file->lineno); + } + + /* Print error message */ + va_start(args, fmt); + if (fmt) + { + fprintf(stderr, "reason: "); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + fflush(stderr); + } + va_end(args); + + /* Clean up and exit */ free_used_memory(); my_end(MY_CHECK_ERROR); + + if (!silent) + printf("skipped\n"); + exit(62); } -static void verbose_msg(const char *fmt, ...) + +void abort_not_in_this_version() +{ + die("Not available in mysqltest for MySQL %s", VERSION); +} + + +void verbose_msg(const char *fmt, ...) { va_list args; DBUG_ENTER("verbose_msg"); @@ -613,23 +806,20 @@ static void verbose_msg(const char *fmt, ...) DBUG_VOID_RETURN; va_start(args, fmt); - fprintf(stderr, "mysqltest: "); - if (start_lineno > 0) + if (start_lineno != 0) fprintf(stderr, "At line %u: ", start_lineno); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); + DBUG_VOID_RETURN; } -void init_parser() -{ - parser.current_line= parser.read_lines= 0; - memset(&var_reg, 0, sizeof(var_reg)); -} - +/* + Compare content of the string ds to content of file fname +*/ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) { @@ -645,10 +835,10 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) if (!test_if_hard_path(fname)) { strxmov(eval_file, opt_basedir, fname, NullS); - fn_format(eval_file, eval_file,"","",4); + fn_format(eval_file, eval_file, "", "", MY_UNPACK_FILENAME); } else - fn_format(eval_file, fname,"","",4); + fn_format(eval_file, fname, "", "", MY_UNPACK_FILENAME); if (!my_stat(eval_file, &stat_info, MYF(MY_WME))) die(NullS); @@ -656,22 +846,24 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) { DBUG_PRINT("info",("Size differs: result size: %u file size: %u", ds->length, stat_info.st_size)); + DBUG_PRINT("info",("result: '%s'", ds->str)); DBUG_RETURN(RESULT_LENGTH_MISMATCH); } if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME)))) - die(NullS); + die("Out of memory"); if ((fd = my_open(eval_file, O_RDONLY, MYF(MY_WME))) < 0) - die(NullS); + die("Failed to open file %s", eval_file); if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP))) - die(NullS); + die("Failed to read from file %s, errno: %d", eval_file, errno); tmp[stat_info.st_size] = 0; - init_dynamic_string(&res_ds, "", 0, 65536); + init_dynamic_string(&res_ds, "", stat_info.st_size+256, 256); if (eval_result) { - do_eval(&res_ds, tmp); - res_ptr = res_ds.str; - if ((res_len = res_ds.length) != ds->length) + do_eval(&res_ds, tmp, tmp + stat_info.st_size, FALSE); + res_ptr= res_ds.str; + res_len= res_ds.length; + if (res_len != ds->length) { res= RESULT_LENGTH_MISMATCH; goto err; @@ -688,51 +880,138 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) err: if (res && eval_result) - str_to_file(fn_format(eval_file, fname, "", ".eval",2), res_ptr, - res_len); + str_to_file(fn_format(eval_file, fname, "", ".eval", + MY_REPLACE_EXT), + res_ptr, res_len); + dynstr_free(&res_ds); my_free((gptr) tmp, MYF(0)); my_close(fd, MYF(MY_WME)); - dynstr_free(&res_ds); DBUG_RETURN(res); } -static int check_result(DYNAMIC_STRING* ds, const char *fname, - my_bool require_option) + +/* + Check the content of ds against content of file fname + + SYNOPSIS + check_result + ds - content to be checked + fname - name of file to check against + require_option - if set and check fails, the test will be aborted + with the special exit code "not supported test" + + RETURN VALUES + error - the function will not return + +*/ + +void check_result(DYNAMIC_STRING* ds, const char *fname, + my_bool require_option) { - int error= RESULT_OK; int res= dyn_string_cmp(ds, fname); + DBUG_ENTER("check_result"); if (res && require_option) - abort_not_supported_test(); + { + char reason[FN_REFLEN]; + fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR); + abort_not_supported_test("Test requires: '%s'", reason); + } switch (res) { case RESULT_OK: break; /* ok */ case RESULT_LENGTH_MISMATCH: - verbose_msg("Result length mismatch"); - error= RESULT_LENGTH_MISMATCH; + dump_result_to_reject_file(fname, ds->str, ds->length); + die("Result length mismatch"); break; case RESULT_CONTENT_MISMATCH: - verbose_msg("Result content mismatch"); - error= RESULT_CONTENT_MISMATCH; + dump_result_to_reject_file(fname, ds->str, ds->length); + die("Result content mismatch"); break; default: /* impossible */ die("Unknown error code from dyn_string_cmp()"); } - if (error) - reject_dump(fname, ds->str, ds->length); - return error; + + DBUG_VOID_RETURN; } -VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, +static byte *get_var_key(const byte* var, uint* len, + my_bool __attribute__((unused)) t) +{ + register char* key; + key = ((VAR*)var)->name; + *len = ((VAR*)var)->name_len; + return (byte*)key; +} + + +VAR *var_init(VAR *v, const char *name, int name_len, const char *val, + int val_len) +{ + int val_alloc_len; + VAR *tmp_var; + if (!name_len && name) + name_len = strlen(name); + if (!val_len && val) + val_len = strlen(val) ; + val_alloc_len = val_len + 16; /* room to grow */ + if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) + + name_len+1, MYF(MY_WME)))) + die("Out of memory"); + + tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; + tmp_var->alloced = (v == 0); + + if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME)))) + die("Out of memory"); + + memcpy(tmp_var->name, name, name_len); + if (val) + { + memcpy(tmp_var->str_val, val, val_len); + tmp_var->str_val[val_len]= 0; + } + tmp_var->name_len = name_len; + tmp_var->str_val_len = val_len; + tmp_var->alloced_len = val_alloc_len; + tmp_var->int_val = (val) ? atoi(val) : 0; + tmp_var->int_dirty = 0; + tmp_var->env_s = 0; + return tmp_var; +} + + +void var_free(void *v) +{ + my_free(((VAR*) v)->str_val, MYF(MY_WME)); + if (((VAR*)v)->alloced) + my_free((char*) v, MYF(MY_WME)); +} + + +VAR* var_from_env(const char *name, const char *def_val) +{ + const char *tmp; + VAR *v; + if (!(tmp = getenv(name))) + tmp = def_val; + + v = var_init(0, name, strlen(name), tmp, strlen(tmp)); + my_hash_insert(&var_hash, (byte*)v); + return v; +} + + +VAR* var_get(const char *var_name, const char **var_name_end, my_bool raw, my_bool ignore_not_existing) { int digit; - VAR* v; + VAR *v; DBUG_ENTER("var_get"); - DBUG_PRINT("enter",("var_name: %s",var_name)); + DBUG_PRINT("enter", ("var_name: %s",var_name)); if (*var_name != '$') goto err; @@ -751,16 +1030,16 @@ VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, die("Empty variable"); } length= (uint) (var_name - save_var_name); - if (length >= MAX_VAR_NAME) + if (length >= MAX_VAR_NAME_LENGTH) die("Too long variable name: %s", save_var_name); if (!(v = (VAR*) hash_search(&var_hash, save_var_name, length))) { - char buff[MAX_VAR_NAME+1]; + char buff[MAX_VAR_NAME_LENGTH+1]; strmake(buff, save_var_name, length); v= var_from_env(buff, ""); } - var_name--; /* Point at last character */ + var_name--; /* Point at last character */ } else v = var_reg + digit; @@ -781,7 +1060,8 @@ err: DBUG_RETURN(0); } -static VAR *var_obtain(const char *name, int len) + +VAR *var_obtain(const char *name, int len) { VAR* v; if ((v = (VAR*)hash_search(&var_hash, name, len))) @@ -791,30 +1071,231 @@ static VAR *var_obtain(const char *name, int len) return v; } -int var_set(const char *var_name, const char *var_name_end, - const char *var_val, const char *var_val_end) + +/* + - if variable starts with a $ it is regarded as a local test varable + - if not it is treated as a environment variable, and the corresponding + environment variable will be updated +*/ + +void var_set(const char *var_name, const char *var_name_end, + const char *var_val, const char *var_val_end) { - int digit; - VAR* v; + int digit, env_var= 0; + VAR *v; DBUG_ENTER("var_set"); DBUG_PRINT("enter", ("var_name: '%.*s' = '%.*s' (length: %d)", (int) (var_name_end - var_name), var_name, (int) (var_val_end - var_val), var_val, (int) (var_val_end - var_val))); - if (*var_name++ != '$') - { - var_name--; - die("Variable name in %s does not start with '$'", var_name); - } - digit = *var_name - '0'; + if (*var_name != '$') + env_var= 1; + else + var_name++; + + digit= *var_name - '0'; if (!(digit < 10 && digit >= 0)) { - v = var_obtain(var_name, (uint) (var_name_end - var_name)); + v= var_obtain(var_name, (uint) (var_name_end - var_name)); } else - v = var_reg + digit; - DBUG_RETURN(eval_expr(v, var_val, (const char**)&var_val_end)); + v= var_reg + digit; + + eval_expr(v, var_val, (const char**) &var_val_end); + + if (env_var) + { + char buf[1024], *old_env_s= v->env_s; + if (v->int_dirty) + { + sprintf(v->str_val, "%d", v->int_val); + v->int_dirty= 0; + v->str_val_len= strlen(v->str_val); + } + strxmov(buf, v->name, "=", v->str_val, NullS); + if (!(v->env_s= my_strdup(buf, MYF(MY_WME)))) + die("Out of memory"); + putenv(v->env_s); + my_free((gptr)old_env_s, MYF(MY_ALLOW_ZERO_PTR)); + } + DBUG_VOID_RETURN; +} + +/* + Store an integer (typically the returncode of the last SQL) + statement in the mysqltest builtin variable $mysql_errno, by + simulating of a user statement "let $mysql_errno= " +*/ + +void var_set_errno(int sql_errno) +{ + /* TODO MASV make easier */ + const char *var_name= "$mysql_errno"; + char var_val[21]; + uint length= my_sprintf(var_val, (var_val, "%d", sql_errno)); + var_set(var_name, var_name + 12, var_val, var_val + length); + return; +} + + +/* + Set variable from the result of a query + + SYNOPSIS + var_query_set() + var variable to set from query + query start of query string to execute + query_end end of the query string to execute + + + DESCRIPTION + let @ = `` + + Execute the query and assign the first row of result to var as + a tab separated strings + + Also assign each column of the result set to + variable "$_" + Thus the tab separated output can be read from $ and + and each individual column can be read as $_ + +*/ + +void var_query_set(VAR *var, const char *query, const char** query_end) +{ + char* end = (char*)((query_end && *query_end) ? + *query_end : query + strlen(query)); + MYSQL_RES *res; + MYSQL_ROW row; + MYSQL* mysql = &cur_con->mysql; + DBUG_ENTER("var_query_set"); + LINT_INIT(res); + + while (end > query && *end != '`') + --end; + if (query == end) + die("Syntax error in query, missing '`'"); + ++query; + + if (mysql_real_query(mysql, query, (int)(end - query)) || + !(res = mysql_store_result(mysql))) + { + *end = 0; + die("Error running query '%s': %d %s", query, + mysql_errno(mysql), mysql_error(mysql)); + } + + if ((row = mysql_fetch_row(res)) && row[0]) + { + /* + Concatenate all row results with tab in between to allow us to work + with results from many columns (for example from SHOW VARIABLES) + */ + DYNAMIC_STRING result; + uint i; + ulong *lengths; + char *end; +#ifdef NOT_YET + MYSQL_FIELD *fields= mysql_fetch_fields(res); +#endif + + init_dynamic_string(&result, "", 2048, 2048); + lengths= mysql_fetch_lengths(res); + for (i=0; i < mysql_num_fields(res); i++) + { + if (row[0]) + { +#ifdef NOT_YET + /* Add to _ */ + uint j; + char var_col_name[MAX_VAR_NAME_LENGTH]; + uint length= snprintf(var_col_name, MAX_VAR_NAME_LENGTH, + "$%s_%s", var->name, fields[i].name); + /* Convert characters not allowed in variable names to '_' */ + for (j= 1; j < length; j++) + { + if (!my_isvar(charset_info,var_col_name[j])) + var_col_name[j]= '_'; + } + var_set(var_col_name, var_col_name + length, + row[i], row[i] + lengths[i]); +#endif + /* Add column to tab separated string */ + dynstr_append_mem(&result, row[i], lengths[i]); + } + dynstr_append_mem(&result, "\t", 1); + } + end= result.str + result.length-1; + eval_expr(var, result.str, (const char**) &end); + dynstr_free(&result); + } + else + eval_expr(var, "", 0); + + mysql_free_result(res); + DBUG_VOID_RETURN; +} + + +void var_copy(VAR *dest, VAR *src) +{ + dest->int_val= src->int_val; + dest->int_dirty= src->int_dirty; + + /* Alloc/realloc data for str_val in dest */ + if (dest->alloced_len < src->alloced_len && + !(dest->str_val= dest->str_val + ? my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME)) + : my_malloc(src->alloced_len, MYF(MY_WME)))) + die("Out of memory"); + else + dest->alloced_len= src->alloced_len; + + /* Copy str_val data to dest */ + dest->str_val_len= src->str_val_len; + if (src->str_val_len) + memcpy(dest->str_val, src->str_val, src->str_val_len); +} + + +void eval_expr(VAR *v, const char *p, const char **p_end) +{ + static int MIN_VAR_ALLOC= 32; /* MASV why 32? */ + VAR *vp; + if (*p == '$') + { + if ((vp= var_get(p, p_end, 0, 0))) + { + var_copy(v, vp); + return; + } + } + else if (*p == '`') + { + var_query_set(v, p, p_end); + } + else + { + int new_val_len = (p_end && *p_end) ? + (int) (*p_end - p) : (int) strlen(p); + if (new_val_len + 1 >= v->alloced_len) + { + v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ? + MIN_VAR_ALLOC : new_val_len + 1; + if (!(v->str_val = + v->str_val ? my_realloc(v->str_val, v->alloced_len+1, + MYF(MY_WME)) : + my_malloc(v->alloced_len+1, MYF(MY_WME)))) + die("Out of memory"); + } + v->str_val_len = new_val_len; + memcpy(v->str_val, p, new_val_len); + v->str_val[new_val_len] = 0; + v->int_val=atoi(p); + v->int_dirty=0; + } + return; } @@ -828,7 +1309,7 @@ int open_file(const char *name) strxmov(buff, opt_basedir, name, NullS); name=buff; } - fn_format(buff,name,"","",4); + fn_format(buff, name, "", "", MY_UNPACK_FILENAME); if (cur_file == file_stack_end) die("Source directives are nesting too deep"); @@ -839,43 +1320,640 @@ int open_file(const char *name) die("Could not open file %s", buff); } cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); - *++lineno=1; + cur_file->lineno=1; DBUG_RETURN(0); } /* - Check for unexpected "junk" after the end of query - This is normally caused by missing delimiters + Source and execute the given file + + SYNOPSIS + do_source() + query called command + + DESCRIPTION + source + + Open the file and execute it + */ -int check_eol_junk(const char *eol) +void do_source(struct st_command *command) { - const char *p= eol; - DBUG_ENTER("check_eol_junk"); - DBUG_PRINT("enter", ("eol: %s", eol)); - /* Remove all spacing chars except new line */ - while (*p && my_isspace(charset_info, *p) && (*p != '\n')) - p++; + DYNAMIC_STRING ds_filename; + const struct command_arg source_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to source" + }; + DBUG_ENTER("do_source"); - /* Check for extra delimiter */ - if (*p && !strncmp(p, delimiter, delimiter_length)) - die("Extra delimiter \"%s\" found", delimiter); + check_command_args(command, command->first_argument, source_args, + sizeof(source_args)/sizeof(struct command_arg), + ' '); - /* Allow trailing # comment */ - if (*p && *p != '#') + /* + If this file has already been sourced, don't source it again. + It's already available in the q_lines cache. + */ + if (parser.current_line < (parser.read_lines - 1)) + ; /* Do nothing */ + else { - if (*p == '\n') - die("Missing delimiter"); - die("End of line junk detected: \"%s\"", p); + DBUG_PRINT("info", ("sourcing file: %s", ds_filename.str)); + open_file(ds_filename.str); } - DBUG_RETURN(0); + + dynstr_free(&ds_filename); + return; } -/* ugly long name, but we are following the convention */ -int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused))) +#ifdef __WIN__ +/* Variables used for temuprary sh files used for emulating Unix on Windows */ +char tmp_sh_name[64], tmp_sh_cmd[70]; + +void init_tmp_sh_file() { + /* Format a name for the tmp sh file that is unique for this process */ + my_snprintf(tmp_sh_name, sizeof(tmp_sh_name), "tmp_%d.sh", getpid()); + /* Format the command to execute in order to run the script */ + my_snprintf(tmp_sh_cmd, sizeof(tmp_sh_cmd), "sh %s", tmp_sh_name); +} + + +void free_tmp_sh_file() +{ + my_delete(tmp_sh_name, MYF(0)); +} +#endif + + +FILE* my_popen(DYNAMIC_STRING *ds_cmd, const char *mode) +{ +#ifdef __WIN__ + /* Dump the command into a sh script file and execute with popen */ + str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length); + return popen(tmp_sh_cmd, mode); +#else + return popen(ds_cmd->str, mode); +#endif +} + + +/* + Execute given command. + + SYNOPSIS + do_exec() + query called command + + DESCRIPTION + exec + + Execute the text between exec and end of line in a subprocess. + The error code returned from the subprocess is checked against the + expected error array, previously set with the --error command. + It can thus be used to execute a command that shall fail. + + NOTE + Although mysqltest is executed from cygwin shell, the command will be + executed in "cmd.exe". Thus commands like "rm" etc can NOT be used, use + system for those commands. +*/ + +void do_exec(struct st_command *command) +{ + int error; + char buf[1024]; + FILE *res_file; + char *cmd= command->first_argument; + DYNAMIC_STRING ds_cmd; + DBUG_ENTER("do_exec"); + DBUG_PRINT("enter", ("cmd: '%s'", cmd)); + + while (*cmd && my_isspace(charset_info, *cmd)) + cmd++; + if (!*cmd) + die("Missing argument in exec"); + command->last_argument= command->end; + + init_dynamic_string(&ds_cmd, 0, command->query_len+256, 256); + /* Eval the command, thus replacing all environment variables */ + do_eval(&ds_cmd, cmd, command->end, TRUE); + cmd= ds_cmd.str; + + DBUG_PRINT("info", ("Executing '%s' as '%s'", + command->first_argument, cmd)); + + if (!(res_file= my_popen(&ds_cmd, "r")) && command->abort_on_error) + die("popen(\"%s\", \"r\") failed", command->first_argument); + + while (fgets(buf, sizeof(buf), res_file)) + { + if (disable_result_log) + { + buf[strlen(buf)-1]=0; + DBUG_PRINT("exec_result",("%s", buf)); + } + else + { + replace_dynstr_append(&ds_res, buf); + } + } + error= pclose(res_file); + if (error > 0) + { + uint status= WEXITSTATUS(error), i; + my_bool ok= 0; + + if (command->abort_on_error) + die("command \"%s\" failed", command->first_argument); + + DBUG_PRINT("info", + ("error: %d, status: %d", error, status)); + for (i= 0; i < command->expected_errors.count; i++) + { + DBUG_PRINT("info", ("expected error: %d", + command->expected_errors.err[i].code.errnum)); + if ((command->expected_errors.err[i].type == ERR_ERRNO) && + (command->expected_errors.err[i].code.errnum == status)) + { + ok= 1; + DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d", + command->first_argument, status)); + } + } + if (!ok) + die("command \"%s\" failed with wrong error: %d", + command->first_argument, status); + } + else if (command->expected_errors.err[0].type == ERR_ERRNO && + command->expected_errors.err[0].code.errnum != 0) + { + /* Error code we wanted was != 0, i.e. not an expected success */ + die("command \"%s\" succeeded - should have failed with errno %d...", + command->first_argument, command->expected_errors.err[0].code.errnum); + } + + dynstr_free(&ds_cmd); + DBUG_VOID_RETURN; +} + +enum enum_operator +{ + DO_DEC, + DO_INC +}; + + +/* + Decrease or increase the value of a variable + + SYNOPSIS + do_modify_var() + query called command + operator operation to perform on the var + + DESCRIPTION + dec $var_name + inc $var_name + +*/ + +int do_modify_var(struct st_command *command, + enum enum_operator operator) +{ + const char *p= command->first_argument; + VAR* v; + if (!*p) + die("Missing argument to %.*s", command->first_word_len, command->query); + if (*p != '$') + die("The argument to %.*s must be a variable (start with $)", + command->first_word_len, command->query); + v= var_get(p, &p, 1, 0); + switch (operator) { + case DO_DEC: + v->int_val--; + break; + case DO_INC: + v->int_val++; + break; + default: + die("Invalid operator to do_modify_var"); + break; + } + v->int_dirty= 1; + command->last_argument= (char*)++p; + return 0; +} + + +/* + Wrapper for 'system' function + + NOTE + If mysqltest is executed from cygwin shell, the command will be + executed in the "windows command interpreter" cmd.exe and we prepend "sh" + to make it be executed by cygwins "bash". Thus commands like "rm", + "mkdir" as well as shellscripts can executed by "system" in Windows. + +*/ + +int my_system(DYNAMIC_STRING* ds_cmd) +{ +#ifdef __WIN__ + /* Dump the command into a sh script file and execute with system */ + str_to_file(tmp_sh_name, ds_cmd->str, ds_cmd->length); + return system(tmp_sh_cmd); +#else + return system(ds_cmd->str); +#endif +} + + +/* + SYNOPSIS + do_system + command called command + + DESCRIPTION + system + + Eval the query to expand any $variables in the command. + Execute the command with the "system" command. + +*/ + +void do_system(struct st_command *command) +{ + DYNAMIC_STRING ds_cmd; + DBUG_ENTER("do_system"); + + if (strlen(command->first_argument) == 0) + die("Missing arguments to system, nothing to do!"); + + init_dynamic_string(&ds_cmd, 0, command->query_len + 64, 256); + + /* Eval the system command, thus replacing all environment variables */ + do_eval(&ds_cmd, command->first_argument, command->end, TRUE); + + DBUG_PRINT("info", ("running system command '%s' as '%s'", + command->first_argument, ds_cmd.str)); + if (my_system(&ds_cmd)) + { + if (command->abort_on_error) + die("system command '%s' failed", command->first_argument); + + /* If ! abort_on_error, log message and continue */ + dynstr_append(&ds_res, "system command '"); + replace_dynstr_append(&ds_res, command->first_argument); + dynstr_append(&ds_res, "' failed\n"); + } + + command->last_argument= command->end; + dynstr_free(&ds_cmd); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_remove_file + command called command + + DESCRIPTION + remove_file + Remove the file +*/ + +void do_remove_file(struct st_command *command) +{ + int error; + DYNAMIC_STRING ds_filename; + const struct command_arg rm_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to delete" + }; + DBUG_ENTER("do_remove_file"); + + check_command_args(command, command->first_argument, + rm_args, sizeof(rm_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("removing file: %s", ds_filename.str)); + error= my_delete(ds_filename.str, MYF(0)) != 0; + handle_command_error(command, error); + dynstr_free(&ds_filename); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_copy_file + command command handle + + DESCRIPTION + copy_file + Copy to + + NOTE! Will fail if exists +*/ + +void do_copy_file(struct st_command *command) +{ + int error; + DYNAMIC_STRING ds_from_file; + DYNAMIC_STRING ds_to_file; + const struct command_arg copy_file_args[] = { + "from_file", ARG_STRING, TRUE, &ds_from_file, "Filename to copy from", + "to_file", ARG_STRING, TRUE, &ds_to_file, "Filename to copy to" + }; + DBUG_ENTER("do_copy_file"); + + check_command_args(command, command->first_argument, + copy_file_args, + sizeof(copy_file_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("Copy %s to %s", ds_from_file.str, ds_to_file.str)); + error= (my_copy(ds_from_file.str, ds_to_file.str, + MYF(MY_DONT_OVERWRITE_FILE)) != 0); + handle_command_error(command, error); + dynstr_free(&ds_from_file); + dynstr_free(&ds_to_file); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_file_exists + command called command + + DESCRIPTION + fiile_exist + Check if file exists +*/ + +void do_file_exist(struct st_command *command) +{ + int error; + DYNAMIC_STRING ds_filename; + const struct command_arg file_exist_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist" + }; + DBUG_ENTER("do_file_exist"); + + check_command_args(command, command->first_argument, + file_exist_args, + sizeof(file_exist_args)/sizeof(struct command_arg), + ' '); + + DBUG_PRINT("info", ("Checking for existence of file: %s", ds_filename.str)); + error= (access(ds_filename.str, F_OK) != 0); + handle_command_error(command, error); + dynstr_free(&ds_filename); + DBUG_VOID_RETURN; +} + + +/* + Read characters from line buffer or file. This is needed to allow + my_ungetc() to buffer MAX_DELIMITER_LENGTH characters for a file + + NOTE: + This works as long as one doesn't change files (with 'source file_name') + when there is things pushed into the buffer. This should however not + happen for any tests in the test suite. +*/ + +int my_getc(FILE *file) +{ + if (line_buffer_pos == line_buffer) + return fgetc(file); + return *--line_buffer_pos; +} + + +void my_ungetc(int c) +{ + *line_buffer_pos++= (char) c; +} + + +void read_until_delimiter(DYNAMIC_STRING *ds, + DYNAMIC_STRING *ds_delimiter) +{ + int c; + DBUG_ENTER("read_until_delimiter"); + DBUG_PRINT("enter", ("delimiter: %s, length: %d", + ds_delimiter->str, ds_delimiter->length)); + + if (ds_delimiter->length > MAX_DELIMITER_LENGTH) + die("Max delimiter length(%d) exceeded", MAX_DELIMITER_LENGTH); + + /* Read from file until delimiter is found */ + while (1) + { + c= my_getc(cur_file->file); + + if (c == '\n') + cur_file->lineno++; + + if (feof(cur_file->file)) + die("End of file encountered before '%s' delimiter was found", + ds_delimiter->str); + + if (match_delimiter(c, ds_delimiter->str, ds_delimiter->length)) + { + DBUG_PRINT("exit", ("Found delimiter '%s'", ds_delimiter->str)); + break; + } + dynstr_append_mem(ds, (const char*)&c, 1); + } + DBUG_PRINT("exit", ("ds: %s", ds->str)); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_write_file + command called command + + DESCRIPTION + write_file []; + + <...> + < what to write line n> + EOF + + --write_file ; + + <...> + < what to write line n> + EOF + + Write everything between the "write_file" command and 'delimiter' + to "file_name" + + NOTE! Overwrites existing file + + Default is EOF + +*/ + +void do_write_file(struct st_command *command) +{ + DYNAMIC_STRING ds_content; + DYNAMIC_STRING ds_filename; + DYNAMIC_STRING ds_delimiter; + const struct command_arg write_file_args[] = { + "filename", ARG_STRING, TRUE, &ds_filename, "File to write to", + "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" + }; + DBUG_ENTER("do_write_file"); + + check_command_args(command, + command->first_argument, + write_file_args, + sizeof(write_file_args)/sizeof(struct command_arg), + ' '); + + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + + init_dynamic_string(&ds_content, "", 1024, 1024); + read_until_delimiter(&ds_content, &ds_delimiter); + DBUG_PRINT("info", ("Writing to file: %s", ds_filename.str)); + str_to_file(ds_filename.str, ds_content.str, ds_content.length); + dynstr_free(&ds_content); + dynstr_free(&ds_filename); + dynstr_free(&ds_delimiter); + DBUG_VOID_RETURN; +} + + +/* + SYNOPSIS + do_perl + command command handle + + DESCRIPTION + perl []; + + <...> + + EOF + + Execute everything after "perl" until as perl. + Useful for doing more advanced things + but still being able to execute it on all platforms. + + Default is EOF +*/ + +void do_perl(struct st_command *command) +{ + int error; + char buf[FN_REFLEN]; + FILE *res_file; + DYNAMIC_STRING ds_script; + DYNAMIC_STRING ds_delimiter; + const struct command_arg perl_args[] = { + "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" + }; + DBUG_ENTER("do_perl"); + + check_command_args(command, + command->first_argument, + perl_args, + sizeof(perl_args)/sizeof(struct command_arg), + ' '); + + /* If no delimiter was provided, use EOF */ + if (ds_delimiter.length == 0) + dynstr_set(&ds_delimiter, "EOF"); + + init_dynamic_string(&ds_script, "", 1024, 1024); + read_until_delimiter(&ds_script, &ds_delimiter); + + DBUG_PRINT("info", ("Executing perl: %s", ds_script.str)); + + /* Format a name for a tmp .pl file that is unique for this process */ + my_snprintf(buf, sizeof(buf), "%s/tmp/tmp_%d.pl", + getenv("MYSQLTEST_VARDIR"), getpid()); + str_to_file(buf, ds_script.str, ds_script.length); + + /* Format the perl command */ + my_snprintf(buf, sizeof(buf), "perl %s/tmp/tmp_%d.pl", + getenv("MYSQLTEST_VARDIR"), getpid()); + + if (!(res_file= popen(buf, "r")) && command->abort_on_error) + die("popen(\"%s\", \"r\") failed", buf); + + while (fgets(buf, sizeof(buf), res_file)) + { + if (disable_result_log) + { + buf[strlen(buf)-1]=0; + DBUG_PRINT("exec_result",("%s", buf)); + } + else + { + replace_dynstr_append(&ds_res, buf); + } + } + error= pclose(res_file); + handle_command_error(command, WEXITSTATUS(error)); + dynstr_free(&ds_script); + dynstr_free(&ds_delimiter); + DBUG_VOID_RETURN; +} + + +/* + Print the content between echo and to result file. + Evaluate all variables in the string before printing, allow + for variable names to be escaped using \ + + SYNOPSIS + do_echo() + command called command + + DESCRIPTION + echo text + Print the text after echo until end of command to result file + + echo $ + Print the content of the variable to result file + + echo Some text $ + Print "Some text" plus the content of the variable to + result file + + echo Some text \$ + Print "Some text" plus $ to result file +*/ + +int do_echo(struct st_command *command) +{ + DYNAMIC_STRING ds_echo; + + init_dynamic_string(&ds_echo, "", command->query_len, 256); + do_eval(&ds_echo, command->first_argument, command->end, FALSE); + dynstr_append_mem(&ds_res, ds_echo.str, ds_echo.length); + dynstr_append_mem(&ds_res, "\n", 1); + dynstr_free(&ds_echo); + command->last_argument= command->end; + return(0); +} + + +void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) +{ + static int SLAVE_POLL_INTERVAL= 300000; MYSQL* mysql = &cur_con->mysql; for (;;) { @@ -899,454 +1977,15 @@ int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused))) break; my_sleep(SLAVE_POLL_INTERVAL); } - return 0; -} - -int do_require_manager(struct st_query *query __attribute__((unused)) ) -{ - if (!manager) - abort_not_supported_test(); - return 0; -} - -#ifndef EMBEDDED_LIBRARY -int do_server_start(struct st_query *q) -{ - return do_server_op(q, "start"); -} - -int do_server_stop(struct st_query *q) -{ - return do_server_op(q, "stop"); -} - -int do_server_op(struct st_query *q, const char *op) -{ - char *p= q->first_argument; - char com_buf[256], *com_p; - if (!manager) - { - die("Manager is not initialized, manager commands are not possible"); - } - com_p= strmov(com_buf,op); - com_p= strmov(com_p,"_exec "); - if (!*p) - die("Missing server name in server_%s", op); - while (*p && !my_isspace(charset_info, *p)) - *com_p++= *p++; - *com_p++= ' '; - com_p= int10_to_str(manager_wait_timeout, com_p, 10); - *com_p++= '\n'; - *com_p= 0; - if (mysql_manager_command(manager, com_buf, (int)(com_p-com_buf))) - die("Error in command: %s(%d)", manager->last_error, manager->last_errno); - while (!manager->eof) - { - if (mysql_manager_fetch_line(manager, com_buf, sizeof(com_buf))) - die("Error fetching result line: %s(%d)", manager->last_error, - manager->last_errno); - } - - q->last_argument= p; - return 0; -} -#endif - - -/* - Source and execute the given file - - SYNOPSIS - do_source() - query called command - - DESCRIPTION - source - - Open the file and execute it - -*/ - -int do_source(struct st_query *query) -{ - char *p= query->first_argument, *name; - if (!*p) - die("Missing file name in source"); - name= p; - while (*p && !my_isspace(charset_info,*p)) - p++; - if (*p) - *p++= 0; - query->last_argument= p; - /* - If this file has already been sourced, don't source it again. - It's already available in the q_lines cache. - */ - if (parser.current_line < (parser.read_lines - 1)) - return 0; - return open_file(name); + return; } -/* - Execute given command. - - SYNOPSIS - do_exec() - query called command - - DESCRIPTION - exec - - Execute the text between exec and end of line in a subprocess. - The error code returned from the subprocess is checked against the - expected error array, previously set with the --error command. - It can thus be used to execute a command that shall fail. - -*/ - -static void do_exec(struct st_query *query) +void do_sync_with_master2(long offset) { - int error; - DYNAMIC_STRING *ds= NULL; - DYNAMIC_STRING ds_tmp; - char buf[1024]; - FILE *res_file; - char *cmd= query->first_argument; - DBUG_ENTER("do_exec"); - - while (*cmd && my_isspace(charset_info, *cmd)) - cmd++; - if (!*cmd) - die("Missing argument in exec"); - query->last_argument= query->end; - - DBUG_PRINT("info", ("Executing '%s'", cmd)); - - if (!(res_file= popen(cmd, "r")) && query->abort_on_error) - die("popen(\"%s\", \"r\") failed", cmd); - - if (disable_result_log) - { - while (fgets(buf, sizeof(buf), res_file)) - { - buf[strlen(buf)-1]=0; - DBUG_PRINT("exec_result",("%s", buf)); - } - } - else - { - if (query->record_file[0]) - { - init_dynamic_string(&ds_tmp, "", 16384, 65536); - ds= &ds_tmp; - } - else - ds= &ds_res; - - while (fgets(buf, sizeof(buf), res_file)) - replace_dynstr_append_mem(ds, buf, strlen(buf)); - } - error= pclose(res_file); - if (error != 0) - { - uint status= WEXITSTATUS(error), i; - my_bool ok= 0; - - if (query->abort_on_error) - die("command \"%s\" failed", cmd); - - DBUG_PRINT("info", - ("error: %d, status: %d", error, status)); - for (i= 0; i < query->expected_errors; i++) - { - DBUG_PRINT("info", ("expected error: %d", - query->expected_errno[i].code.errnum)); - if ((query->expected_errno[i].type == ERR_ERRNO) && - (query->expected_errno[i].code.errnum == status)) - { - ok= 1; - DBUG_PRINT("info", ("command \"%s\" failed with expected error: %d", - cmd, status)); - } - } - if (!ok) - die("command \"%s\" failed with wrong error: %d", - cmd, status); - } - else if (query->expected_errno[0].type == ERR_ERRNO && - query->expected_errno[0].code.errnum != 0) - { - /* Error code we wanted was != 0, i.e. not an expected success */ - die("command \"%s\" succeeded - should have failed with errno %d...", - cmd, query->expected_errno[0].code.errnum); - } - - if (!disable_result_log) - { - if (glob_replace) - free_replace(); - - if (record) - { - if (!query->record_file[0] && !result_file) - die("Missing result file"); - if (!result_file) - str_to_file(query->record_file, ds->str, ds->length); - } - else if (query->record_file[0]) - { - error= check_result(ds, query->record_file, query->require_file); - } - if (ds == &ds_tmp) - dynstr_free(&ds_tmp); - } -} - - -int var_query_set(VAR* v, const char *p, const char** p_end) -{ - char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p)); MYSQL_RES *res; MYSQL_ROW row; - MYSQL* mysql = &cur_con->mysql; - LINT_INIT(res); - - while (end > p && *end != '`') - --end; - if (p == end) - die("Syntax error in query, missing '`'"); - ++p; - - if (mysql_real_query(mysql, p, (int)(end - p)) || - !(res = mysql_store_result(mysql))) - { - *end = 0; - die("Error running query '%s': %s", p, mysql_error(mysql)); - } - - if ((row = mysql_fetch_row(res)) && row[0]) - { - /* - Concatenate all row results with tab in between to allow us to work - with results from many columns (for example from SHOW VARIABLES) - */ - DYNAMIC_STRING result; - uint i; - ulong *lengths; - char *end; - - init_dynamic_string(&result, "", 16384, 65536); - lengths= mysql_fetch_lengths(res); - for (i=0; i < mysql_num_fields(res); i++) - { - if (row[0]) - dynstr_append_mem(&result, row[i], lengths[i]); - dynstr_append_mem(&result, "\t", 1); - } - end= result.str + result.length-1; - eval_expr(v, result.str, (const char**) &end); - dynstr_free(&result); - } - else - eval_expr(v, "", 0); - - mysql_free_result(res); - return 0; -} - -void var_copy(VAR *dest, VAR *src) -{ - dest->int_val= src->int_val; - dest->int_dirty= src->int_dirty; - - /* Alloc/realloc data for str_val in dest */ - if (dest->alloced_len < src->alloced_len && - !(dest->str_val= dest->str_val - ? my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME)) - : my_malloc(src->alloced_len, MYF(MY_WME)))) - die("Out of memory"); - else - dest->alloced_len= src->alloced_len; - - /* Copy str_val data to dest */ - dest->str_val_len= src->str_val_len; - if (src->str_val_len) - memcpy(dest->str_val, src->str_val, src->str_val_len); -} - -int eval_expr(VAR* v, const char *p, const char** p_end) -{ - VAR* vp; - if (*p == '$') - { - if ((vp = var_get(p,p_end,0,0))) - { - var_copy(v, vp); - return 0; - } - } - else if (*p == '`') - { - return var_query_set(v, p, p_end); - } - else - { - int new_val_len = (p_end && *p_end) ? - (int) (*p_end - p) : (int) strlen(p); - if (new_val_len + 1 >= v->alloced_len) - { - v->alloced_len = (new_val_len < MIN_VAR_ALLOC - 1) ? - MIN_VAR_ALLOC : new_val_len + 1; - if (!(v->str_val = - v->str_val ? my_realloc(v->str_val, v->alloced_len+1, - MYF(MY_WME)) : - my_malloc(v->alloced_len+1, MYF(MY_WME)))) - die("Out of memory"); - } - v->str_val_len = new_val_len; - memcpy(v->str_val, p, new_val_len); - v->str_val[new_val_len] = 0; - v->int_val=atoi(p); - v->int_dirty=0; - return 0; - } - - die("Invalid expr: %s", p); - return 1; -} - - -enum enum_operator -{ - DO_DEC, - DO_INC -}; - -/* - Decrease or increase the value of a variable - - SYNOPSIS - do_modify_var() - query called command - name human readable name of operator - operator operation to perform on the var - - DESCRIPTION - dec $var_name - inc $var_name - -*/ - -int do_modify_var(struct st_query *query, const char *name, - enum enum_operator operator) -{ - const char *p= query->first_argument; - VAR* v; - if (!*p) - die("Missing arguments to %s", name); - if (*p != '$') - die("First argument to %s must be a variable (start with $)", name); - v= var_get(p, &p, 1, 0); - switch (operator){ - case DO_DEC: - v->int_val--; - break; - case DO_INC: - v->int_val++; - break; - default: - die("Invalid operator to do_operator"); - break; - } - v->int_dirty= 1; - query->last_argument= (char*)++p; - return 0; -} - - -int do_system(struct st_query *q) -{ - char *p=q->first_argument; - VAR v; - var_init(&v, 0, 0, 0, 0); - eval_expr(&v, p, 0); /* NULL terminated */ - if (v.str_val_len) - { - char expr_buf[1024]; - if ((uint)v.str_val_len > sizeof(expr_buf) - 1) - v.str_val_len = sizeof(expr_buf) - 1; - memcpy(expr_buf, v.str_val, v.str_val_len); - expr_buf[v.str_val_len] = 0; - DBUG_PRINT("info", ("running system command '%s'", expr_buf)); - if (system(expr_buf)) - { - if (q->abort_on_error) - die("system command '%s' failed", expr_buf); - /* If ! abort_on_error, display message and continue */ - verbose_msg("system command '%s' failed", expr_buf); - } - } - else - die("Missing arguments to system, nothing to do!"); - var_free(&v); - q->last_argument= q->end; - return 0; -} - - -/* - Print the content between echo and to result file. - If content is a variable, the variable value will be retrieved - - SYNOPSIS - do_echo() - q called command - - DESCRIPTION - Usage 1: - echo text - Print the text after echo until end of command to result file - - Usage 2: - echo $ - Print the content of the variable to result file - -*/ - -int do_echo(struct st_query *q) -{ - char *p= q->first_argument; - DYNAMIC_STRING *ds; - DYNAMIC_STRING ds_tmp; - VAR v; - var_init(&v,0,0,0,0); - - if (q->record_file[0]) - { - init_dynamic_string(&ds_tmp, "", 256, 512); - ds= &ds_tmp; - } - else - ds= &ds_res; - - eval_expr(&v, p, 0); /* NULL terminated */ - if (v.str_val_len) - dynstr_append_mem(ds, v.str_val, v.str_val_len); - dynstr_append_mem(ds, "\n", 1); - var_free(&v); - if (ds == &ds_tmp) - dynstr_free(&ds_tmp); - q->last_argument= q->end; - return 0; -} - - -int do_sync_with_master2(long offset) -{ - MYSQL_RES* res; - MYSQL_ROW row; - MYSQL* mysql= &cur_con->mysql; + MYSQL *mysql= &cur_con->mysql; char query_buf[FN_REFLEN+128]; int tries= 0; int rpl_parse; @@ -1362,10 +2001,10 @@ int do_sync_with_master2(long offset) wait_for_position: if (mysql_query(mysql, query_buf)) - die("failed in %s: %d: %s", query_buf, mysql_errno(mysql), + die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql), mysql_error(mysql)); - if (!(last_result= res= mysql_store_result(mysql))) + if (!(res= mysql_store_result(mysql))) die("mysql_store_result() returned NULL for '%s'", query_buf); if (!(row= mysql_fetch_row(res))) die("empty result in %s", query_buf); @@ -1375,24 +2014,24 @@ wait_for_position: It may be that the slave SQL thread has not started yet, though START SLAVE has been issued ? */ - if (tries++ == 3) + if (tries++ == 30) die("could not sync with master ('%s' returned NULL)", query_buf); - sleep(1); /* So at most we will wait 3 seconds and make 4 tries */ + sleep(1); /* So at most we will wait 30 seconds and make 31 tries */ mysql_free_result(res); goto wait_for_position; } mysql_free_result(res); - last_result=0; if (rpl_parse) mysql_enable_rpl_parse(mysql); - return 0; + return; } -int do_sync_with_master(struct st_query *query) + +void do_sync_with_master(struct st_command *command) { long offset= 0; - char *p= query->first_argument; + char *p= command->first_argument; const char *offset_start= p; if (*offset_start) { @@ -1401,33 +2040,177 @@ int do_sync_with_master(struct st_query *query) if(*p && !my_isspace(charset_info, *p)) die("Invalid integer argument \"%s\"", offset_start); - query->last_argument= p; + command->last_argument= p; } - return do_sync_with_master2(offset); + do_sync_with_master2(offset); + return; } + +/* + when ndb binlog is on, this call will wait until last updated epoch + (locally in the mysqld) has been received into the binlog +*/ int do_save_master_pos() { - MYSQL_RES* res; + MYSQL_RES *res; MYSQL_ROW row; - MYSQL* mysql = &cur_con->mysql; + MYSQL *mysql = &cur_con->mysql; const char *query; int rpl_parse; rpl_parse = mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); +#ifdef HAVE_NDB_BINLOG + /* + Wait for ndb binlog to be up-to-date with all changes + done on the local mysql server + */ + { + ulong have_ndbcluster; + if (mysql_query(mysql, query= "show variables like 'have_ndbcluster'")) + die("'%s' failed: %d %s", query, + mysql_errno(mysql), mysql_error(mysql)); + if (!(res= mysql_store_result(mysql))) + die("mysql_store_result() returned NULL for '%s'", query); + if (!(row= mysql_fetch_row(res))) + die("Query '%s' returned empty result", query); + + have_ndbcluster= strcmp("YES", row[1]) == 0; + mysql_free_result(res); + + if (have_ndbcluster) + { + ulonglong start_epoch= 0, applied_epoch= 0, + latest_epoch=0, latest_trans_epoch=0, + latest_handled_binlog_epoch= 0, latest_received_binlog_epoch= 0, + latest_applied_binlog_epoch= 0; + int count= 0; + int do_continue= 1; + while (do_continue) + { + const char binlog[]= "binlog"; + const char latest_epoch_str[]= + "latest_epoch="; + const char latest_trans_epoch_str[]= + "latest_trans_epoch="; + const char latest_received_binlog_epoch_str[]= + "latest_received_binlog_epoch"; + const char latest_handled_binlog_epoch_str[]= + "latest_handled_binlog_epoch="; + const char latest_applied_binlog_epoch_str[]= + "latest_applied_binlog_epoch="; + if (count) + sleep(1); + if (mysql_query(mysql, query= "show engine ndb status")) + die("failed in '%s': %d %s", query, + mysql_errno(mysql), mysql_error(mysql)); + if (!(res= mysql_store_result(mysql))) + die("mysql_store_result() returned NULL for '%s'", query); + while ((row= mysql_fetch_row(res))) + { + if (strcmp(row[1], binlog) == 0) + { + const char *status= row[2]; + + /* latest_epoch */ + while (*status && strncmp(status, latest_epoch_str, + sizeof(latest_epoch_str)-1)) + status++; + if (*status) + { + status+= sizeof(latest_epoch_str)-1; + latest_epoch= strtoull(status, (char**) 0, 10); + } + else + die("result does not contain '%s' in '%s'", + latest_epoch_str, query); + /* latest_trans_epoch */ + while (*status && strncmp(status, latest_trans_epoch_str, + sizeof(latest_trans_epoch_str)-1)) + status++; + if (*status) + { + status+= sizeof(latest_trans_epoch_str)-1; + latest_trans_epoch= strtoull(status, (char**) 0, 10); + } + else + die("result does not contain '%s' in '%s'", + latest_trans_epoch_str, query); + /* latest_received_binlog_epoch */ + while (*status && + strncmp(status, latest_received_binlog_epoch_str, + sizeof(latest_received_binlog_epoch_str)-1)) + status++; + if (*status) + { + status+= sizeof(latest_received_binlog_epoch_str)-1; + latest_received_binlog_epoch= strtoull(status, (char**) 0, 10); + } + else + die("result does not contain '%s' in '%s'", + latest_received_binlog_epoch_str, query); + /* latest_handled_binlog */ + while (*status && + strncmp(status, latest_handled_binlog_epoch_str, + sizeof(latest_handled_binlog_epoch_str)-1)) + status++; + if (*status) + { + status+= sizeof(latest_handled_binlog_epoch_str)-1; + latest_handled_binlog_epoch= strtoull(status, (char**) 0, 10); + } + else + die("result does not contain '%s' in '%s'", + latest_handled_binlog_epoch_str, query); + /* latest_applied_binlog_epoch */ + while (*status && + strncmp(status, latest_applied_binlog_epoch_str, + sizeof(latest_applied_binlog_epoch_str)-1)) + status++; + if (*status) + { + status+= sizeof(latest_applied_binlog_epoch_str)-1; + latest_applied_binlog_epoch= strtoull(status, (char**) 0, 10); + } + else + die("result does not contain '%s' in '%s'", + latest_applied_binlog_epoch_str, query); + if (count == 0) + start_epoch= latest_trans_epoch; + break; + } + } + if (!row) + die("result does not contain '%s' in '%s'", + binlog, query); + if (latest_applied_binlog_epoch > applied_epoch) + count= 0; + applied_epoch= latest_applied_binlog_epoch; + count++; + if (latest_handled_binlog_epoch >= start_epoch) + do_continue= 0; + else if (count > 30) + { + break; + } + mysql_free_result(res); + } + } + } +#endif if (mysql_query(mysql, query= "show master status")) - die("failed in show master status: %d: %s", + die("failed in 'show master status': %d %s", mysql_errno(mysql), mysql_error(mysql)); - if (!(last_result =res = mysql_store_result(mysql))) + if (!(res = mysql_store_result(mysql))) die("mysql_store_result() retuned NULL for '%s'", query); if (!(row = mysql_fetch_row(res))) die("empty result in show master status"); strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); master_pos.pos = strtoul(row[1], (char**) 0, 10); - mysql_free_result(res); last_result=0; + mysql_free_result(res); if (rpl_parse) mysql_enable_rpl_parse(mysql); @@ -1440,25 +2223,30 @@ int do_save_master_pos() Assign the variable with SYNOPSIS - do_let() - query called command + do_let() + query called command DESCRIPTION - let $= + let $= - - is the string string found between the $ and = - - is the content between the = and , it may span - multiple line and contain any characters except - - is a string containing of one or more chars, default is ; + - is the string string found between the $ and = + - is the content between the = and , it may span + multiple line and contain any characters except + - is a string containing of one or more chars, default is ; RETURN VALUES - Program will die if error detected + Program will die if error detected */ -int do_let(struct st_query *query) +void do_let(struct st_command *command) { - char *p= query->first_argument; - char *var_name, *var_name_end, *var_val_start; + char *p= command->first_argument; + char *var_name, *var_name_end; + DYNAMIC_STRING let_rhs_expr; + + DBUG_ENTER("do_let"); + + init_dynamic_string(&let_rhs_expr, "", 512, 2048); /* Find */ if (!*p) @@ -1467,7 +2255,8 @@ int do_let(struct st_query *query) while (*p && (*p != '=') && !my_isspace(charset_info,*p)) p++; var_name_end= p; - if (var_name+1 == var_name_end) + if (var_name == var_name_end || + (var_name+1 == var_name_end && *var_name == '$')) die("Missing variable name in let"); while (my_isspace(charset_info,*p)) p++; @@ -1477,29 +2266,19 @@ int do_let(struct st_query *query) /* Find start of */ while (*p && my_isspace(charset_info,*p)) p++; - var_val_start= p; - query->last_argument= query->end; + + do_eval(&let_rhs_expr, p, command->end, FALSE); + + command->last_argument= command->end; /* Assign var_val to var_name */ - return var_set(var_name, var_name_end, var_val_start, query->end); + var_set(var_name, var_name_end, let_rhs_expr.str, + (let_rhs_expr.str + let_rhs_expr.length)); + dynstr_free(&let_rhs_expr); + DBUG_VOID_RETURN; } -/* - Store an integer (typically the returncode of the last SQL) - statement in the mysqltest builtin variable $mysql_errno, by - simulating of a user statement "let $mysql_errno= " -*/ - -int var_set_errno(int sql_errno) -{ - const char *var_name= "$mysql_errno"; - char var_val[21]; - uint length= my_sprintf(var_val, (var_val, "%d", sql_errno)); - return var_set(var_name, var_name + 12, var_val, var_val + length); -} - - -int do_rpl_probe(struct st_query *query __attribute__((unused))) +int do_rpl_probe(struct st_command *command __attribute__((unused))) { DBUG_ENTER("do_rpl_probe"); if (mysql_rpl_probe(&cur_con->mysql)) @@ -1508,14 +2287,14 @@ int do_rpl_probe(struct st_query *query __attribute__((unused))) } -int do_enable_rpl_parse(struct st_query *query __attribute__((unused))) +int do_enable_rpl_parse(struct st_command *command __attribute__((unused))) { mysql_enable_rpl_parse(&cur_con->mysql); return 0; } -int do_disable_rpl_parse(struct st_query *query __attribute__((unused))) +int do_disable_rpl_parse(struct st_command *command __attribute__((unused))) { mysql_disable_rpl_parse(&cur_con->mysql); return 0; @@ -1523,17 +2302,17 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused))) /* - Sleep the number of specifed seconds + Sleep the number of specified seconds SYNOPSIS - do_sleep() - q called command - real_sleep use the value from opt_sleep as number of seconds to sleep - if real_sleep is false + do_sleep() + q called command + real_sleep use the value from opt_sleep as number of seconds to sleep + if real_sleep is false DESCRIPTION - sleep - real_sleep + sleep + real_sleep The difference between the sleep and real_sleep commands is that sleep uses the delay from the --sleep command-line option if there is one. @@ -1544,39 +2323,42 @@ int do_disable_rpl_parse(struct st_query *query __attribute__((unused))) used for cpu-independent delays. */ -int do_sleep(struct st_query *query, my_bool real_sleep) +int do_sleep(struct st_command *command, my_bool real_sleep) { int error= 0; - char *p= query->first_argument; - char *sleep_start, *sleep_end= query->end; + char *p= command->first_argument; + char *sleep_start, *sleep_end= command->end; double sleep_val; while (my_isspace(charset_info, *p)) p++; if (!*p) - die("Missing argument to %.*s", query->first_word_len, query->query); + die("Missing argument to %.*s", command->first_word_len, command->query); sleep_start= p; /* Check that arg starts with a digit, not handled by my_strtod */ if (!my_isdigit(charset_info, *sleep_start)) - die("Invalid argument to %.*s \"%s\"", query->first_word_len, query->query, - query->first_argument); + die("Invalid argument to %.*s \"%s\"", command->first_word_len, + command->query,command->first_argument); sleep_val= my_strtod(sleep_start, &sleep_end, &error); if (error) - die("Invalid argument to %.*s \"%s\"", query->first_word_len, query->query, - query->first_argument); + die("Invalid argument to %.*s \"%s\"", command->first_word_len, + command->query, command->first_argument); /* Fixed sleep time selected by --sleep option */ - if (opt_sleep && !real_sleep) + if (opt_sleep >= 0 && !real_sleep) sleep_val= opt_sleep; - my_sleep((ulong) (sleep_val * 1000000L)); - query->last_argument= sleep_end; + DBUG_PRINT("info", ("sleep_val: %f", sleep_val)); + if (sleep_val) + my_sleep((ulong) (sleep_val * 1000000L)); + command->last_argument= sleep_end; return 0; } -static void get_file_name(char *filename, struct st_query *q) + +void do_get_file_name(char *filename, struct st_command *command) { - char *p= q->first_argument, *name; + char *p= command->first_argument, *name; if (!*p) die("Missing file name argument"); name= p; @@ -1584,13 +2366,14 @@ static void get_file_name(char *filename, struct st_query *q) p++; if (*p) *p++= 0; - q->last_argument= p; + command->last_argument= p; strmake(filename, name, FN_REFLEN); } -static void set_charset(struct st_query *q) + +void do_set_charset(struct st_command *command) { - char *charset_name= q->first_argument; + char *charset_name= command->first_argument; char *p; if (!charset_name || !*charset_name) @@ -1601,49 +2384,182 @@ static void set_charset(struct st_query *q) p++; if(*p) *p++= 0; - q->last_argument= p; + command->last_argument= p; charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); if (!charset_info) - abort_not_supported_test(); + abort_not_supported_test("Test requires charset '%s'", charset_name); } -static uint get_errcodes(match_err *to,struct st_query *q) + +#if MYSQL_VERSION_ID >= 50000 +/* List of error names to error codes, available from 5.0 */ +typedef struct { - char *p= q->first_argument; + const char *name; + long code; +} st_error; + +static st_error global_error_names[] = +{ +#include + { 0, 0 } +}; +#define HAVE_MYSQLD_ERNAME +#endif + + +uint get_errcode_from_name(char *error_name, char *error_end) +{ +#ifdef HAVE_MYSQLD_ERNAME + DBUG_ENTER("get_errcode_from_name"); + + /* SQL error as string */ + st_error *e= global_error_names; + DBUG_PRINT("enter", ("error_name: %s", error_name)); + + /* Loop through the array of known error names */ + for (; e->name; e++) + { + /* + If we get a match, we need to check the length of the name we + matched against in case it was longer than what we are checking + (as in ER_WRONG_VALUE vs. ER_WRONG_VALUE_COUNT). + */ + if (!strncmp(error_name, e->name, (int) (error_end - error_name)) && + (uint) strlen(e->name) == (uint) (error_end - error_name)) + { + return (uint) e->code; + break; + } + } + if (!e->name) + die("Unknown SQL error name '%s'", error_name); +#else + LINT_INIT(error_name); + LINT_INIT(error_end); + abort_not_in_this_version(); +#endif + return 0; +} + + +void do_get_errcodes(struct st_command *command) +{ + struct st_match_err *to= saved_expected_errors.err; + char *p= command->first_argument; uint count= 0; - DBUG_ENTER("get_errcodes"); + + DBUG_ENTER("do_get_errcodes"); if (!*p) - die("Missing argument in %s", q->query); + die("Missing argument(s) to 'error'"); do { + char *end; + + /* Skip leading spaces */ + while (*p && *p == ' ') + p++; + + /* Find end */ + end= p; + while (*end && *end != ',' && *end != ' ') + end++; + if (*p == 'S') { - /* SQLSTATE string */ - int i; - p++; - for (i = 0; my_isalnum(charset_info, *p) && i < SQLSTATE_LENGTH; p++, i++) - to[count].code.sqlstate[i]= *p; - to[count].code.sqlstate[i]= '\0'; - to[count].type= ERR_SQLSTATE; + /* + SQLSTATE string + - Must be SQLSTATE_LENGTH long + - May contain only digits[0-9] and _uppercase_ letters + */ + p++; /* Step past the S */ + if (end - p != SQLSTATE_LENGTH) + die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH); + + /* Check sqlstate string validity */ + char *to_ptr= to->code.sqlstate; + while (*p && p != end) + { + if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p)) + *to_ptr++= *p++; + else + die("The sqlstate may only consist of digits[0-9] " \ + "and _uppercase_ letters"); + } + + *to_ptr= 0; + to->type= ERR_SQLSTATE; + DBUG_PRINT("info", ("ERR_SQLSTATE: %d", to->code.sqlstate)); + } + else if (*p == 's') + { + die("The sqlstate definition must start with an uppercase S"); + } + else if (*p == 'E') + { + /* Error name string */ + + DBUG_PRINT("info", ("Error name: %s", p)); + to->code.errnum= get_errcode_from_name(p, end); + to->type= ERR_ERRNO; + DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum)); + } + else if (*p == 'e') + { + die("The error name definition must start with an uppercase E"); } else { long val; - p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val); - if (p == NULL) - die("Invalid argument in %s", q->query); - to[count].code.errnum= (uint) val; - to[count].type= ERR_ERRNO; + char *start= p; + /* Check that the string passed to str2int only contain digits */ + while (*p && p != end) + { + if (!my_isdigit(charset_info, *p)) + die("Invalid argument to error: '%s' - "\ + "the errno may only consist of digits[0-9]", + command->first_argument); + p++; + } + + /* Convert the sting to int */ + if (!str2int(start, 10, (long) INT_MIN, (long) INT_MAX, &val)) + die("Invalid argument to error: '%s'", command->first_argument); + + to->code.errnum= (uint) val; + to->type= ERR_ERRNO; + DBUG_PRINT("info", ("ERR_ERRNO: %d", to->code.errnum)); } + to++; count++; - } while (*(p++) == ','); - q->last_argument= (p - 1); - to[count].type= ERR_EMPTY; /* End of data */ - DBUG_RETURN(count); + + if (count >= (sizeof(saved_expected_errors.err) / + sizeof(struct st_match_err))) + die("Too many errorcodes specified"); + + /* Set pointer to the end of the last error code */ + p= end; + + /* Find next ',' */ + while (*p && *p != ',') + p++; + + if (*p) + p++; /* Step past ',' */ + + } while (*p); + + command->last_argument= p; + to->type= ERR_EMPTY; /* End of data */ + + DBUG_PRINT("info", ("Expected errors: %d", count)); + saved_expected_errors.count= count; + DBUG_VOID_RETURN; } + /* Get a string; Return ptr to end of string Strings may be surrounded by " or ' @@ -1651,11 +2567,10 @@ static uint get_errcodes(match_err *to,struct st_query *q) If string is a '$variable', return the value of the variable. */ - -static char *get_string(char **to_ptr, char **from_ptr, - struct st_query *q) +char *get_string(char **to_ptr, char **from_ptr, + struct st_command *command) { - reg1 char c,sep; + char c, sep; char *to= *to_ptr, *from= *from_ptr, *start=to; DBUG_ENTER("get_string"); @@ -1701,7 +2616,7 @@ static char *get_string(char **to_ptr, char **from_ptr, *to++=c; } if (*from != ' ' && *from) - die("Wrong string argument in %s", q->query); + die("Wrong string argument in %s", command->query); while (my_isspace(charset_info,*from)) /* Point to next string */ from++; @@ -1725,93 +2640,46 @@ static char *get_string(char **to_ptr, char **from_ptr, } -/* - Get arguments for replace. The syntax is: - replace from to [from to ...] - Where each argument may be quoted with ' or " - A argument may also be a variable, in which case the value of the - variable is replaced. -*/ - -static void get_replace(struct st_query *q) +void set_reconnect(MYSQL* mysql, int val) { - uint i; - char *from= q->first_argument; - char *buff,*start; - char word_end_chars[256],*pos; - POINTER_ARRAY to_array,from_array; - DBUG_ENTER("get_replace"); - - free_replace(); - - bzero((char*) &to_array,sizeof(to_array)); - bzero((char*) &from_array,sizeof(from_array)); - if (!*from) - die("Missing argument in %s", q->query); - start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); - while (*from) - { - char *to=buff; - to=get_string(&buff, &from, q); - if (!*from) - die("Wrong number of arguments to replace_result in '%s'", q->query); - insert_pointer_name(&from_array,to); - to=get_string(&buff, &from, q); - insert_pointer_name(&to_array,to); - } - for (i=1,pos=word_end_chars ; i < 256 ; i++) - if (my_isspace(charset_info,i)) - *pos++= i; - *pos=0; /* End pointer */ - if (!(glob_replace=init_replace((char**) from_array.typelib.type_names, - (char**) to_array.typelib.type_names, - (uint) from_array.typelib.count, - word_end_chars)) || - initialize_replace_buffer()) - die("Can't initialize replace from '%s'", q->query); - free_pointer_array(&from_array); - free_pointer_array(&to_array); - my_free(start, MYF(0)); - q->last_argument= q->end; - DBUG_VOID_RETURN; +#if MYSQL_VERSION_ID < 50000 + mysql->reconnect= val; +#else + int reconnect= val; + mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); +#endif } -void free_replace() + +struct st_connection * find_connection_by_name(const char *name) { - DBUG_ENTER("free_replace"); - if (glob_replace) + struct st_connection *con; + for (con= connections; con < next_con; con++) { - my_free((char*) glob_replace,MYF(0)); - glob_replace=0; - free_replace_buffer(); + if (!strcmp(con->name, name)) + { + return con; + } } - DBUG_VOID_RETURN; + return 0; /* Connection not found */ } int select_connection_name(const char *name) { - struct connection *con; DBUG_ENTER("select_connection2"); DBUG_PRINT("enter",("name: '%s'", name)); - for (con= cons; con < next_con; con++) - { - if (!strcmp(con->name, name)) - { - cur_con= con; - DBUG_RETURN(0); - } - } - die("connection '%s' not found in connection pool", name); - DBUG_RETURN(1); /* Never reached */ + if (!(cur_con= find_connection_by_name(name))) + die("connection '%s' not found in connection pool", name); + DBUG_RETURN(0); } -int select_connection(struct st_query *query) +int select_connection(struct st_command *command) { char *name; - char *p= query->first_argument; + char *p= command->first_argument; DBUG_ENTER("select_connection"); if (!*p) @@ -1821,33 +2689,38 @@ int select_connection(struct st_query *query) p++; if (*p) *p++= 0; - query->last_argument= p; + command->last_argument= p; return select_connection_name(name); } -int close_connection(struct st_query *q) +void do_close_connection(struct st_command *command) { - char *p= q->first_argument, *name; - struct connection *con; + char *p= command->first_argument, *name; + struct st_connection *con; + DBUG_ENTER("close_connection"); DBUG_PRINT("enter",("name: '%s'",p)); if (!*p) - die("Missing connection name in connect"); + die("Missing connection name in disconnect"); name= p; while (*p && !my_isspace(charset_info,*p)) p++; if (*p) *p++= 0; - q->last_argument= p; - for (con= cons; con < next_con; con++) + command->last_argument= p; + + /* Loop through connection pool for connection to close */ + for (con= connections; con < next_con; con++) { + DBUG_PRINT("info", ("con->name: %s", con->name)); if (!strcmp(con->name, name)) { + DBUG_PRINT("info", ("Closing connection %s", con->name)); #ifndef EMBEDDED_LIBRARY - if (q->type == Q_DIRTY_CLOSE) + if (command->type == Q_DIRTY_CLOSE) { if (con->mysql.net.vio) { @@ -1857,172 +2730,353 @@ int close_connection(struct st_query *q) } #endif mysql_close(&con->mysql); - DBUG_RETURN(0); + if (con->util_mysql) + mysql_close(con->util_mysql); + con->util_mysql= 0; + my_free(con->name, MYF(0)); + + /* + When the connection is closed set name to "closed_connection" + to make it possible to reuse the connection name. + The connection slot will not be reused + */ + if (!(con->name = my_strdup("closed_connection", MYF(MY_WME)))) + die("Out of memory"); + + DBUG_VOID_RETURN; } } die("connection '%s' not found in connection pool", name); - DBUG_RETURN(1); /* Never reached */ } /* - This one now is a hack - we may want to improve in in the - future to handle quotes. For now we assume that anything that is not - a comma, a space or ) belongs to the argument. space is a chopper, comma or - ) are delimiters/terminators + Connect to a server doing several retries if needed. + + SYNOPSIS + safe_connect() + con - connection structure to be used + host, user, pass, - connection parameters + db, port, sock + + NOTE + + Sometimes in a test the client starts before + the server - to solve the problem, we try again + after some sleep if connection fails the first + time + + This function will try to connect to the given server + "opt_max_connect_retries" times and sleep "connection_retry_sleep" + seconds between attempts before finally giving up. + This helps in situation when the client starts + before the server (which happens sometimes). + It will only ignore connection errors during these retries. + */ -char* safe_get_param(char *str, char** arg, const char *msg) +void safe_connect(MYSQL* mysql, const char *name, const char *host, + const char *user, const char *pass, const char *db, + int port, const char *sock) { - DBUG_ENTER("safe_get_param"); - while (*str && my_isspace(charset_info,*str)) - str++; - *arg= str; - for (; *str && *str != ',' && *str != ')' ; str++) + int failed_attempts= 0; + static ulong connection_retry_sleep= 100000; /* Microseconds */ + + DBUG_ENTER("safe_connect"); + while(!mysql_real_connect(mysql, host,user, pass, db, port, sock, + CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) { - if (my_isspace(charset_info,*str)) - *str= 0; - } - if (!*str) - die(msg); + /* + Connect failed - *str++= 0; - DBUG_RETURN(str); -} + Only allow retry if this was an error indicating the server + could not be contacted + */ -#ifndef EMBEDDED_LIBRARY -void init_manager() -{ - if (!(manager=mysql_manager_init(0))) - die("Failed in mysql_manager_init()"); - if (!mysql_manager_connect(manager,manager_host,manager_user, - manager_pass,manager_port)) - die("Could not connect to MySQL manager: %s(%d)",manager->last_error, - manager->last_errno); - -} -#endif - -int safe_connect(MYSQL* con, const char *host, const char *user, - const char *pass, - const char *db, int port, const char *sock) -{ - int con_error = 1; - int i; - for (i = 0; i < MAX_CON_TRIES; ++i) - { - if (mysql_real_connect(con, host,user, pass, db, port, sock, - CLIENT_MULTI_STATEMENTS)) + if (mysql_errno(mysql) == CR_CONNECTION_ERROR && + failed_attempts < opt_max_connect_retries) + my_sleep(connection_retry_sleep); + else { - con_error = 0; - break; + if (failed_attempts > 0) + die("Could not open connection '%s' after %d attempts: %d %s", name, + failed_attempts, mysql_errno(mysql), mysql_error(mysql)); + else + die("Could not open connection '%s': %d %s", name, + mysql_errno(mysql), mysql_error(mysql)); } - sleep(CON_RETRY_SLEEP); + failed_attempts++; } - return con_error; + DBUG_VOID_RETURN; } -int do_connect(struct st_query *q) +/* + Connect to a server and handle connection errors in case they occur. + + SYNOPSIS + connect_n_handle_errors() + q - context of connect "query" (command) + con - connection structure to be used + host, user, pass, - connection parameters + db, port, sock + + DESCRIPTION + This function will try to establish a connection to server and handle + possible errors in the same manner as if "connect" was usual SQL-statement + (If error is expected it will ignore it once it occurs and log the + "statement" to the query log). + Unlike safe_connect() it won't do several attempts. + + RETURN VALUES + 1 - Connected + 0 - Not connected + +*/ + +int connect_n_handle_errors(struct st_command *command, + MYSQL* con, const char* host, + const char* user, const char* pass, + const char* db, int port, const char* sock) { - char *con_name, *con_user,*con_pass, *con_host, *con_port_str, - *con_db, *con_sock; - char *p= q->first_argument; - char buff[FN_REFLEN]; - int con_port; - int free_con_sock= 0; + DYNAMIC_STRING *ds; + + ds= &ds_res; + + /* Only log if an error is expected */ + if (!command->abort_on_error && + !disable_query_log) + { + /* + Log the connect to result log + */ + dynstr_append_mem(ds, "connect(", 8); + replace_dynstr_append(ds, host); + dynstr_append_mem(ds, ",", 1); + replace_dynstr_append(ds, user); + dynstr_append_mem(ds, ",", 1); + replace_dynstr_append(ds, pass); + dynstr_append_mem(ds, ",", 1); + if (db) + replace_dynstr_append(ds, db); + dynstr_append_mem(ds, ",", 1); + replace_dynstr_append_uint(ds, port); + dynstr_append_mem(ds, ",", 1); + if (sock) + replace_dynstr_append(ds, sock); + dynstr_append_mem(ds, ")", 1); + dynstr_append_mem(ds, delimiter, delimiter_length); + dynstr_append_mem(ds, "\n", 1); + } + if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, + CLIENT_MULTI_STATEMENTS)) + { + handle_error(command, mysql_errno(con), mysql_error(con), + mysql_sqlstate(con), ds); + return 0; /* Not connected */ + } + + handle_no_error(command); + return 1; /* Connected */ +} + + +/* + Open a new connection to MySQL Server with the parameters + specified. Make the new connection the current connection. + + SYNOPSIS + do_connect() + q called command + + DESCRIPTION + connect(,,,[,[,[,[]]]]); + connect ,,,[,[,[,[]]]]; + + - name of the new connection + - hostname of server + - user to connect as + - password used when connecting + - initial db when connected + - server port + - server socket + - options to use for the connection + * SSL - use SSL if available + * COMPRESS - use compression if available + +*/ + +void do_connect(struct st_command *command) +{ + int con_port= port; + char *con_options; + bool con_ssl= 0, con_compress= 0; + char *ptr; + + DYNAMIC_STRING ds_connection_name; + DYNAMIC_STRING ds_host; + DYNAMIC_STRING ds_user; + DYNAMIC_STRING ds_password; + DYNAMIC_STRING ds_database; + DYNAMIC_STRING ds_port; + DYNAMIC_STRING ds_sock; + DYNAMIC_STRING ds_options; + const struct command_arg connect_args[] = { + "connection name", ARG_STRING, TRUE, &ds_connection_name, + "Name of the connection", + "host", ARG_STRING, TRUE, &ds_host, "Host to connect to", + "user", ARG_STRING, FALSE, &ds_user, "User to connect as", + "passsword", ARG_STRING, FALSE, &ds_password, + "Password used when connecting", + "database", ARG_STRING, FALSE, &ds_database, + "Dtabase to select after connect", + "port", ARG_STRING, FALSE, &ds_port, "Port to connect to", + "socket", ARG_STRING, FALSE, &ds_sock, "Socket to connect with", + "options", ARG_STRING, FALSE, &ds_options, + "Options to use while connecting" + }; DBUG_ENTER("do_connect"); - DBUG_PRINT("enter",("connect: %s",p)); + DBUG_PRINT("enter",("connect: %s", command->first_argument)); - if (*p != '(') - die("Syntax error in connect - expected '(' found '%c'", *p); - p++; - p= safe_get_param(p, &con_name, "missing connection name"); - p= safe_get_param(p, &con_host, "missing connection host"); - p= safe_get_param(p, &con_user, "missing connection user"); - p= safe_get_param(p, &con_pass, "missing connection password"); - p= safe_get_param(p, &con_db, "missing connection db"); - if (!*p || *p == ';') /* Default port and sock */ + /* Remove parenteses around connect arguments */ + if ((ptr= strstr(command->first_argument, "("))) { - con_port= port; - con_sock= (char*) unix_sock; + /* Replace it with a space */ + *ptr= ' '; + if ((ptr= strstr(command->first_argument, ")"))) + { + /* Replace it with \0 */ + *ptr= 0; + } + else + die("connect - argument list started with '(' must be ended with ')'"); + } + + check_command_args(command, command->first_argument, connect_args, + sizeof(connect_args)/sizeof(struct command_arg), + ','); + + /* Port */ + if (ds_port.length) + { + con_port= atoi(ds_port.str); + if (con_port == 0) + die("Illegal argument for port: '%s'", ds_port.str); + } + + /* Sock */ + if (ds_sock.length) + { + /* + If the socket is specified just as a name without path + append tmpdir in front + */ + if (*ds_sock.str != FN_LIBCHAR) + { + char buff[FN_REFLEN]; + fn_format(buff, ds_sock.str, TMPDIR, "", 0); + dynstr_set(&ds_sock, buff); + } } else { - VAR* var_port, *var_sock; - p= safe_get_param(p, &con_port_str, "missing connection port"); - if (*con_port_str == '$') - { - if (!(var_port= var_get(con_port_str, 0, 0, 0))) - die("Unknown variable '%s'", con_port_str+1); - con_port= var_port->int_val; - } - else - con_port= atoi(con_port_str); - p= safe_get_param(p, &con_sock, "missing connection socket"); - if (*con_sock == '$') - { - if (!(var_sock= var_get(con_sock, 0, 0, 0))) - die("Unknown variable '%s'", con_sock+1); - if (!(con_sock= (char*)my_malloc(var_sock->str_val_len+1, MYF(0)))) - die("Out of memory"); - free_con_sock= 1; - memcpy(con_sock, var_sock->str_val, var_sock->str_val_len); - con_sock[var_sock->str_val_len]= 0; - } + /* No socket specified, use default */ + dynstr_set(&ds_sock, unix_sock); } - q->last_argument= p; + DBUG_PRINT("info", ("socket: %s", ds_sock.str)); - if (next_con == cons_end) - die("Connection limit exhausted - increase MAX_CONS in mysqltest.c"); + + /* Options */ + con_options= ds_options.str; + while (*con_options) + { + char* end= con_options; + while (*end && !my_isspace(charset_info, *end)) + end++; + if (!strncmp(con_options, "SSL", 3)) + con_ssl= 1; + else if (!strncmp(con_options, "COMPRESS", 8)) + con_compress= 1; + else + die("Illegal option to connect: %.*s", end - con_options, con_options); + /* Process next option */ + con_options= end; + } + + if (next_con == connections_end) + die("Connection limit exhausted, you can have max %d connections", + (sizeof(connections)/sizeof(struct st_connection))); + + if (find_connection_by_name(ds_connection_name.str)) + die("Connection %s already exists", ds_connection_name.str); if (!mysql_init(&next_con->mysql)) die("Failed on mysql_init()"); - if (opt_compress) - mysql_options(&next_con->mysql,MYSQL_OPT_COMPRESS,NullS); + if (opt_compress || con_compress) + mysql_options(&next_con->mysql, MYSQL_OPT_COMPRESS, NullS); mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name); #ifdef HAVE_OPENSSL - if (opt_use_ssl) + if (opt_use_ssl || con_ssl) + { mysql_ssl_set(&next_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); +#if MYSQL_VERSION_ID >= 50000 + /* Turn on ssl_verify_server_cert only if host is "localhost" */ + opt_ssl_verify_server_cert= !strcmp(con_host, "localhost"); + mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + &opt_ssl_verify_server_cert); +#endif + } #endif - if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR) - con_sock=fn_format(buff, con_sock, TMPDIR, "",0); - if (!con_db[0]) - con_db= db; - /* Special database to allow one to connect without a database name */ - if (con_db && !strcmp(con_db,"*NO-ONE*")) - con_db= 0; - if ((safe_connect(&next_con->mysql, con_host, - con_user, con_pass, - con_db, con_port, con_sock ? con_sock: 0))) - die("Could not open connection '%s': %s", con_name, - mysql_error(&next_con->mysql)); - if (!(next_con->name= my_strdup(con_name, MYF(MY_WME)))) - die(NullS); - cur_con= next_con++; - if (free_con_sock) - my_free(con_sock, MYF(MY_WME)); - DBUG_RETURN(0); + /* Use default db name */ + if (ds_database.length == 0) + dynstr_set(&ds_database, db); + + /* Special database to allow one to connect without a database name */ + if (ds_database.length && !strcmp(ds_database.str,"*NO-ONE*")) + dynstr_set(&ds_database, ""); + + + if (connect_n_handle_errors(command, &next_con->mysql, + ds_host.str,ds_user.str, + ds_password.str, ds_database.str, + con_port, ds_sock.str)) + { + DBUG_PRINT("info", ("Inserting connection %s in connection pool", + ds_connection_name.str)); + if (!(next_con->name= my_strdup(ds_connection_name.str, MYF(MY_WME)))) + die("Out of memory"); + cur_con= next_con++; + } + + dynstr_free(&ds_connection_name); + dynstr_free(&ds_host); + dynstr_free(&ds_user); + dynstr_free(&ds_password); + dynstr_free(&ds_database); + dynstr_free(&ds_port); + dynstr_free(&ds_sock); + dynstr_free(&ds_options); + DBUG_VOID_RETURN; } -int do_done(struct st_query *q) +int do_done(struct st_command *command) { /* Check if empty block stack */ if (cur_block == block_stack) { - if (*q->query != '}') + if (*command->query != '}') die("Stray 'end' command - end of block before beginning"); die("Stray '}' - end of block before beginning"); } /* Test if inner block has been executed */ - if (cur_block->ok && cur_block->cmd == Q_WHILE) + if (cur_block->ok && cur_block->cmd == cmd_while) { /* Pop block from stack, re-execute outer block */ cur_block--; @@ -2038,12 +3092,41 @@ int do_done(struct st_query *q) } -int do_block(enum enum_commands cmd, struct st_query *q) +/* + Process start of a "if" or "while" statement + + SYNOPSIS + do_block() + cmd Type of block + q called command + + DESCRIPTION + if ([!]) + { + + } + + while ([!]) + { + + } + + Evaluates the and if it evaluates to + greater than zero executes the following code block. + A '!' can be used before the to indicate it should + be executed if it evaluates to zero. + +*/ + +void do_block(enum block_cmd cmd, struct st_command* command) { - char *p= q->first_argument; + char *p= command->first_argument; const char *expr_start, *expr_end; VAR v; - const char *cmd_name= (cmd == Q_WHILE ? "while" : "if"); + const char *cmd_name= (cmd == cmd_while ? "while" : "if"); + my_bool not_expr= FALSE; + DBUG_ENTER("do_block"); + DBUG_PRINT("enter", ("%s", cmd_name)); /* Check stack overflow */ if (cur_block == block_stack_end) @@ -2059,13 +3142,21 @@ int do_block(enum enum_commands cmd, struct st_query *q) cur_block++; cur_block->cmd= cmd; cur_block->ok= FALSE; - return 0; + DBUG_VOID_RETURN; } /* Parse and evaluate test expression */ expr_start= strchr(p, '('); - if (!expr_start) + if (!expr_start++) die("missing '(' in %s", cmd_name); + + /* Check for ! */ + if (*expr_start == '!') + { + not_expr= TRUE; + expr_start++; /* Step past the '!' */ + } + /* Find ending ')' */ expr_end= strrchr(expr_start, ')'); if (!expr_end) die("missing ')' in %s", cmd_name); @@ -2073,61 +3164,62 @@ int do_block(enum enum_commands cmd, struct st_query *q) while (*p && my_isspace(charset_info, *p)) p++; - if (*p == '{') - die("Missing newline between %s and '{'", cmd_name); - if (*p) + if (*p && *p != '{') die("Missing '{' after %s. Found \"%s\"", cmd_name, p); var_init(&v,0,0,0,0); - eval_expr(&v, ++expr_start, &expr_end); + eval_expr(&v, expr_start, &expr_end); /* Define inner block */ cur_block++; cur_block->cmd= cmd; cur_block->ok= (v.int_val ? TRUE : FALSE); + if (not_expr) + cur_block->ok = !cur_block->ok; + + DBUG_PRINT("info", ("OK: %d", cur_block->ok)); + var_free(&v); - return 0; + DBUG_VOID_RETURN; } -/* - Read characters from line buffer or file. This is needed to allow - my_ungetc() to buffer MAX_DELIMITER characters for a file - - NOTE: - This works as long as one doesn't change files (with 'source file_name') - when there is things pushed into the buffer. This should however not - happen for any tests in the test suite. -*/ - -int my_getc(FILE *file) +void do_delimiter(struct st_command* command) { - if (line_buffer_pos == line_buffer) - return fgetc(file); - return *--line_buffer_pos; -} + char* p= command->first_argument; + DBUG_ENTER("do_delimiter"); + DBUG_PRINT("enter", ("first_argument: %s", command->first_argument)); -void my_ungetc(int c) -{ - *line_buffer_pos++= (char) c; + while (*p && my_isspace(charset_info, *p)) + p++; + + if (!(*p)) + die("Can't set empty delimiter"); + + strmake(delimiter, p, sizeof(delimiter) - 1); + delimiter_length= strlen(delimiter); + + DBUG_PRINT("exit", ("delimiter: %s", delimiter)); + command->last_argument= p + delimiter_length; + DBUG_VOID_RETURN; } -my_bool end_of_query(int c) +my_bool match_delimiter(int c, const char *delim, uint length) { uint i; - char tmp[MAX_DELIMITER]; + char tmp[MAX_DELIMITER_LENGTH]; - if (c != *delimiter) + if (c != *delim) return 0; - for (i= 1; i < delimiter_length && - (c= my_getc(cur_file->file)) == *(delimiter + i); + for (i= 1; i < length && + (c= my_getc(cur_file->file)) == *(delim + i); i++) tmp[i]= c; - if (i == delimiter_length) + if (i == length) return 1; /* Found delimiter */ /* didn't find delimiter, push back things that we read */ @@ -2138,44 +3230,51 @@ my_bool end_of_query(int c) } +my_bool end_of_query(int c) +{ + return match_delimiter(c, delimiter, delimiter_length); +} + + /* Read one "line" from the file SYNOPSIS - read_line - buf buffer for the read line - size size of the buffer i.e max size to read + read_line + buf buffer for the read line + size size of the buffer i.e max size to read DESCRIPTION - This function actually reads several lines an adds them to the - buffer buf. It will continue to read until it finds what it believes - is a complete query. + This function actually reads several lines and adds them to the + buffer buf. It continues to read until it finds what it believes + is a complete query. - Normally that means it will read lines until it reaches the - "delimiter" that marks end of query. Default delimiter is ';' - The function should be smart enough not to detect delimiter's - found inside strings surrounded with '"' and '\'' escaped strings. + Normally that means it will read lines until it reaches the + "delimiter" that marks end of query. Default delimiter is ';' + The function should be smart enough not to detect delimiter's + found inside strings surrounded with '"' and '\'' escaped strings. - If the first line in a query starts with '#' or '-' this line is treated - as a comment. A comment is always terminated when end of line '\n' is - reached. + If the first line in a query starts with '#' or '-' this line is treated + as a comment. A comment is always terminated when end of line '\n' is + reached. */ int read_line(char *buf, int size) { - int c; + char c, last_quote; char *p= buf, *buf_end= buf + size - 1; - int no_save= 0; - enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2, - R_ESC_SLASH_Q1, R_ESC_SLASH_Q2, - R_Q2, R_COMMENT, R_LINE_START} state= R_LINE_START; + int skip_char= 0; + enum {R_NORMAL, R_Q, R_SLASH_IN_Q, + R_COMMENT, R_LINE_START} state= R_LINE_START; DBUG_ENTER("read_line"); + LINT_INIT(last_quote); - start_lineno= *lineno; + start_lineno= cur_file->lineno; + DBUG_PRINT("info", ("start_lineno: %d", start_lineno)); for (; p < buf_end ;) { - no_save= 0; + skip_char= 0; c= my_getc(cur_file->file); if (feof(cur_file->file)) { @@ -2187,127 +3286,118 @@ int read_line(char *buf, int size) } my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); cur_file->file_name= 0; - lineno--; - start_lineno= *lineno; if (cur_file == file_stack) { /* We're back at the first file, check if all { have matching } - */ + */ if (cur_block != block_stack) - { - start_lineno= *(lineno+1); die("Missing end of block"); - } - DBUG_RETURN(1); + + *p= 0; + DBUG_PRINT("info", ("end of file")); + DBUG_RETURN(1); } cur_file--; + start_lineno= cur_file->lineno; continue; } - /* Line counting is independent of state */ if (c == '\n') - (*lineno)++; + { + /* Line counting is independent of state */ + cur_file->lineno++; + + /* Convert cr/lf to lf */ + if (p != buf && *(p-1) == '\r') + p--; + } switch(state) { case R_NORMAL: - /* Only accept '{' in the beginning of a line */ if (end_of_query(c)) { *p= 0; + DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); DBUG_RETURN(0); } - else if (c == '\'') - state = R_Q1; - else if (c == '"') - state = R_Q2; - else if (c == '\n') + else if ((c == '{' && + (!strncasecmp(buf, "while", min(5, p - buf)) || + !strncasecmp(buf, "if", min(2, p - buf))))) { - state = R_LINE_START; + /* Only if and while commands can be terminated by { */ + *p++= c; + *p= 0; + DBUG_PRINT("exit", ("Found '{' indicating begining of block")); + DBUG_RETURN(0); + } + else if (c == '\'' || c == '"' || c == '`') + { + last_quote= c; + state= R_Q; } break; + case R_COMMENT: if (c == '\n') { + /* Comments are terminated by newline */ *p= 0; + DBUG_PRINT("exit", ("Found newline in comment")); DBUG_RETURN(0); } break; + case R_LINE_START: - /* Only accept start of comment if this is the first line in query */ - if ((*lineno == start_lineno) && (c == '#' || c == '-')) + if (c == '#' || c == '-') { + /* A # or - in the first position of the line - this is a comment */ state = R_COMMENT; } else if (my_isspace(charset_info, c)) { + /* Skip all space at begining of line */ if (c == '\n') - start_lineno= *lineno; /* Query hasn't started yet */ - no_save= 1; + start_lineno= cur_file->lineno; /* Query hasn't started yet */ + skip_char= 1; + } + else if (end_of_query(c)) + { + *p= 0; + DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_RETURN(0); } else if (c == '}') { - *buf++= '}'; - *buf= 0; - DBUG_RETURN(0); - } - else if (end_of_query(c) || c == '{') - { + /* A "}" need to be by itself in the begining of a line to terminate */ + *p++= c; *p= 0; + DBUG_PRINT("exit", ("Found '}' in begining of a line")); DBUG_RETURN(0); } - else if (c == '\'') - state= R_Q1; - else if (c == '"') - state= R_Q2; + else if (c == '\'' || c == '"' || c == '`') + { + last_quote= c; + state= R_Q; + } else state= R_NORMAL; break; - case R_Q1: - if (c == '\'') - state= R_ESC_Q_Q1; - else if (c == '\\') - state= R_ESC_SLASH_Q1; - break; - case R_ESC_Q_Q1: - if (end_of_query(c)) - { - *p= 0; - DBUG_RETURN(0); - } - if (c != '\'') + case R_Q: + if (c == last_quote) state= R_NORMAL; - else - state= R_Q1; - break; - case R_ESC_SLASH_Q1: - state= R_Q1; + else if (c == '\\') + state= R_SLASH_IN_Q; break; - case R_Q2: - if (c == '"') - state= R_ESC_Q_Q2; - else if (c == '\\') - state= R_ESC_SLASH_Q2; - break; - case R_ESC_Q_Q2: - if (end_of_query(c)) - { - *p= 0; - DBUG_RETURN(0); - } - if (c != '"') - state= R_NORMAL; - else - state= R_Q2; - break; - case R_ESC_SLASH_Q2: - state= R_Q2; + case R_SLASH_IN_Q: + state= R_Q; break; + } - if (!no_save) + if (!skip_char) { /* Could be a multibyte character */ /* This code is based on the code in "sql_load.cc" */ @@ -2325,7 +3415,7 @@ int read_line(char *buf, int size) for (i= 1; i < charlen; i++) { if (feof(cur_file->file)) - goto found_eof; /* FIXME: could we just break here?! */ + goto found_eof; c= my_getc(cur_file->file); *p++ = c; } @@ -2342,102 +3432,191 @@ int read_line(char *buf, int size) *p++= c; } } - *p= 0; /* Always end with \0 */ - DBUG_RETURN(feof(cur_file->file)); + die("The input buffer is too small for this query.x\n" \ + "check your query or increase MAX_QUERY and recompile"); + DBUG_RETURN(0); } + /* - Create a query from a set of lines + Convert the read query to result format version 1 - SYNOPSIS - read_query() - q_ptr pointer where to return the new query + That is: After newline, all spaces need to be skipped + unless the previous char was a quote - DESCRIPTION - Converts lines returned by read_line into a query, this involves - parsing the first word in the read line to find the query type. + This is due to an old bug that has now been fixed, but the + version 1 output format is preserved by using this function - - A -- comment may contain a valid query as the first word after the - comment start. Thus it's always checked to see if that is the case. - The advantage with this approach is to be able to execute commands - terminated by new line '\n' regardless how many "delimiter" it contain. - - If query starts with @ this will specify a file to .... */ -static char read_query_buf[MAX_QUERY]; - -int read_query(struct st_query** q_ptr) +void convert_to_format_v1(char* query) { - char *p= read_query_buf, *p1; - struct st_query* q; - DBUG_ENTER("read_query"); + int last_c_was_quote= 0; + char *p= query, *write= query; + char *end= strend(query); + char last_c; + + while (p <= end) + { + if (*p == '\n' && !last_c_was_quote) + { + *write++ = *p++; /* Save the newline */ + + /* Skip any spaces on next line */ + while (*p && my_isspace(charset_info, *p)) + p++; + + last_c_was_quote= 0; + } + else if (*p == '\'' || *p == '"' || *p == '`') + { + last_c= *p; + *write++ = *p++; + + /* Copy anything until the next quote of same type */ + while (*p && *p != last_c) + *write++ = *p++; + + *write++ = *p++; + + last_c_was_quote= 1; + } + else + { + *write++ = *p++; + last_c_was_quote= 0; + } + } +} + + +/* + Check for unexpected "junk" after the end of query + This is normally caused by missing delimiters +*/ + +void check_eol_junk(const char *eol) +{ + const char *p= eol; + DBUG_ENTER("check_eol_junk"); + DBUG_PRINT("enter", ("eol: %s", eol)); + /* Remove all spacing chars except new line */ + while (*p && my_isspace(charset_info, *p) && (*p != '\n')) + p++; + + /* Check for extra delimiter */ + if (*p && !strncmp(p, delimiter, delimiter_length)) + die("Extra delimiter \"%s\" found", delimiter); + + /* Allow trailing # comment */ + if (*p && *p != '#') + { + if (*p == '\n') + die("Missing delimiter"); + die("End of line junk detected: \"%s\"", p); + } + DBUG_VOID_RETURN; +} + + + +/* + Create a command from a set of lines + + SYNOPSIS + read_command() + command_ptr pointer where to return the new query + + DESCRIPTION + Converts lines returned by read_line into a command, this involves + parsing the first word in the read line to find the command type. + + + A -- comment may contain a valid query as the first word after the + comment start. Thus it's always checked to see if that is the case. + The advantage with this approach is to be able to execute commands + terminated by new line '\n' regardless how many "delimiter" it contain. + +*/ + +#define MAX_QUERY (256*1024) /* 256K -- a test in sp-big is >128K */ +static char read_command_buf[MAX_QUERY]; + +int read_command(struct st_command** command_ptr) +{ + char *p= read_command_buf; + struct st_command* command; + DBUG_ENTER("read_command"); if (parser.current_line < parser.read_lines) { - get_dynamic(&q_lines, (gptr) q_ptr, parser.current_line) ; + get_dynamic(&q_lines, (gptr) command_ptr, parser.current_line) ; DBUG_RETURN(0); } - if (!(*q_ptr= q= (struct st_query*) my_malloc(sizeof(*q), MYF(MY_WME))) || - insert_dynamic(&q_lines, (gptr) &q)) + if (!(*command_ptr= command= + (struct st_command*) my_malloc(sizeof(*command), MYF(MY_WME))) || + insert_dynamic(&q_lines, (gptr) &command)) die(NullS); - q->record_file[0]= 0; - q->require_file= 0; - q->first_word_len= 0; + command->record_file[0]= 0; + command->require_file= 0; + command->first_word_len= 0; + command->query_len= 0; - q->type= Q_UNKNOWN; - q->query_buf= q->query= 0; - if (read_line(read_query_buf, sizeof(read_query_buf))) + command->type= Q_UNKNOWN; + command->query_buf= command->query= 0; + read_command_buf[0]= 0; + if (read_line(read_command_buf, sizeof(read_command_buf))) { - DBUG_PRINT("warning",("too long query")); + check_eol_junk(read_command_buf); DBUG_RETURN(1); } - DBUG_PRINT("info", ("query: %s", read_query_buf)); + + convert_to_format_v1(read_command_buf); + + DBUG_PRINT("info", ("query: %s", read_command_buf)); if (*p == '#') { - q->type= Q_COMMENT; + command->type= Q_COMMENT; /* This goto is to avoid losing the "expected error" info. */ goto end; } - memcpy((gptr) q->expected_errno, (gptr) global_expected_errno, - sizeof(global_expected_errno)); - q->expected_errors= global_expected_errors; - q->abort_on_error= (global_expected_errors == 0 && abort_on_error); + if (!parsing_disabled) + { + memcpy(&command->expected_errors, &saved_expected_errors, + sizeof(saved_expected_errors)); + DBUG_PRINT("info", ("There are %d expected errors", + command->expected_errors.count)); + command->abort_on_error= (command->expected_errors.count == 0 && + abort_on_error); + } + if (p[0] == '-' && p[1] == '-') { - q->type= Q_COMMENT_WITH_COMMAND; + command->type= Q_COMMENT_WITH_COMMAND; p+= 2; /* To calculate first word */ } - else + else if (!parsing_disabled) { while (*p && my_isspace(charset_info, *p)) p++ ; - if (*p == '@') - { - p++; - p1 = q->record_file; - while (!my_isspace(charset_info, *p) && - p1 < q->record_file + sizeof(q->record_file) - 1) - *p1++ = *p++; - *p1 = 0; - } } end: while (*p && my_isspace(charset_info, *p)) p++; - if (!(q->query_buf= q->query= my_strdup(p, MYF(MY_WME)))) + + if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME)))) die(NullS); /* Calculate first word and first argument */ - for (p= q->query; *p && !my_isspace(charset_info, *p) ; p++) ; - q->first_word_len= (uint) (p - q->query); + for (p= command->query; *p && !my_isspace(charset_info, *p) ; p++) ; + command->first_word_len= (uint) (p - command->query); while (*p && my_isspace(charset_info, *p)) p++; - q->first_argument= p; - q->end= strend(q->query); + command->first_argument= p; + command->end= strend(command->query); + command->query_len= (command->end - command->query); parser.read_lines++; DBUG_RETURN(0); } @@ -2445,39 +3624,41 @@ end: static struct my_option my_long_options[] = { - {"debug", '#', "Output debug log. Often this is 'd:t:o,filename'.", - 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, {"basedir", 'b', "Basedir for tests.", (gptr*) &opt_basedir, (gptr*) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"big-test", 'B', "Define BIG_TEST to 1.", (gptr*) &opt_big_test, - (gptr*) &opt_big_test, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"compress", 'C', "Use the compressed server/client protocol.", (gptr*) &opt_compress, (gptr*) &opt_compress, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Display this help and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, - 0, 0, 0, 0, 0, 0}, + {"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statements.", + (gptr*) &cursor_protocol, (gptr*) &cursor_protocol, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"database", 'D', "Database to use.", (gptr*) &db, (gptr*) &db, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#ifdef DBUG_OFF + {"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. Often this is 'd:t:o,filename'.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, +#endif {"host", 'h', "Connect to host.", (gptr*) &host, (gptr*) &host, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"manager-user", OPT_MANAGER_USER, "Undocumented: Used for debugging.", - (gptr*) &manager_user, (gptr*) &manager_user, 0, GET_STR, REQUIRED_ARG, 0, - 0, 0, 0, 0, 0}, - {"manager-host", OPT_MANAGER_HOST, "Undocumented: Used for debugging.", - (gptr*) &manager_host, (gptr*) &manager_host, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, - {"manager-password", OPT_MANAGER_PASSWD, "Undocumented: Used for debugging.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"manager-port", OPT_MANAGER_PORT, "Undocumented: Used for debugging.", - (gptr*) &manager_port, (gptr*) &manager_port, 0, GET_INT, REQUIRED_ARG, - MYSQL_MANAGER_PORT, 0, 0, 0, 0, 0}, - {"manager-wait-timeout", OPT_MANAGER_WAIT_TIMEOUT, - "Undocumented: Used for debugging.", (gptr*) &manager_wait_timeout, - (gptr*) &manager_wait_timeout, 0, GET_INT, REQUIRED_ARG, 3, 0, 0, 0, 0, 0}, + {"include", 'i', "Include SQL before each test case.", (gptr*) &opt_include, + (gptr*) &opt_include, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"mark-progress", OPT_MARK_PROGRESS, + "Write linenumber and elapsed time to .progress ", + (gptr*) &opt_mark_progress, (gptr*) &opt_mark_progress, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"max-connect-retries", OPT_MAX_CONNECT_RETRIES, + "Max number of connection attempts when connecting to server", + (gptr*) &opt_max_connect_retries, (gptr*) &opt_max_connect_retries, 0, + GET_INT, REQUIRED_ARG, 500, 1, 10000, 0, 0, 0}, {"password", 'p', "Password to use when connecting to server.", 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"port", 'P', "Port number to use for connection.", (gptr*) &port, - (gptr*) &port, 0, GET_INT, REQUIRED_ARG, MYSQL_PORT, 0, 0, 0, 0, 0}, + (gptr*) &port, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication", (gptr*) &ps_protocol, (gptr*) &ps_protocol, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -2498,11 +3679,14 @@ static struct my_option my_long_options[] = "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"sleep", 'T', "Sleep always this many seconds on sleep commands.", - (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, 0, 0, 0, + (gptr*) &opt_sleep, (gptr*) &opt_sleep, 0, GET_INT, REQUIRED_ARG, -1, 0, 0, 0, 0, 0}, {"socket", 'S', "Socket file to use for connection.", (gptr*) &unix_sock, (gptr*) &unix_sock, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"sp-protocol", OPT_SP_PROTOCOL, "Use stored procedures for select", + (gptr*) &sp_protocol, (gptr*) &sp_protocol, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #include "sslopt-longopts.h" {"test-file", 'x', "Read test from/in this file (default stdin).", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, @@ -2516,13 +3700,16 @@ static struct my_option my_long_options[] = GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select", + (gptr*) &view_protocol, (gptr*) &view_protocol, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; #include -static void print_version(void) +void print_version(void) { printf("%s Ver %s Distrib %s, for %s (%s)\n",my_progname,MTEST_VERSION, MYSQL_SERVER_VERSION,SYSTEM_TYPE,MACHINE_TYPE); @@ -2543,6 +3730,52 @@ void usage() #include +/* + Read arguments for embedded server and put them into + embedded_server_args[] +*/ + +void read_embedded_server_arguments(const char *name) +{ + char argument[1024],buff[FN_REFLEN], *str=0; + FILE *file; + + if (!test_if_hard_path(name)) + { + strxmov(buff, opt_basedir, name, NullS); + name=buff; + } + fn_format(buff, name, "", "", MY_UNPACK_FILENAME); + + if (!embedded_server_arg_count) + { + embedded_server_arg_count=1; + embedded_server_args[0]= (char*) ""; /* Progname */ + } + if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) + die("Failed to open file %s", buff); + + while (embedded_server_arg_count < MAX_EMBEDDED_SERVER_ARGS && + (str=fgets(argument,sizeof(argument), file))) + { + *(strend(str)-1)=0; /* Remove end newline */ + if (!(embedded_server_args[embedded_server_arg_count]= + (char*) my_strdup(str,MYF(MY_WME)))) + { + my_fclose(file,MYF(0)); + die("Out of memory"); + + } + embedded_server_arg_count++; + } + my_fclose(file,MYF(0)); + if (str) + die("Too many arguments in option file: %s",name); + + return; +} + + static my_bool get_one_option(int optid, const struct my_option *opt __attribute__((unused)), char *argument) @@ -2556,40 +3789,36 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'r': record = 1; break; - case (int)OPT_MANAGER_PASSWD: - my_free(manager_pass,MYF(MY_ALLOW_ZERO_PTR)); - manager_pass=my_strdup(argument, MYF(MY_FAE)); - while (*argument) *argument++= 'x'; /* Destroy argument */ - break; case 'x': + { + char buff[FN_REFLEN]; + if (!test_if_hard_path(argument)) { - char buff[FN_REFLEN]; - if (!test_if_hard_path(argument)) - { - strxmov(buff, opt_basedir, argument, NullS); - argument= buff; - } - fn_format(buff, argument, "", "", 4); - DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0); - if (!(cur_file->file= - my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) - die("Could not open %s: errno = %d", buff, errno); - cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); - break; + strxmov(buff, opt_basedir, argument, NullS); + argument= buff; } + fn_format(buff, argument, "", "", MY_UNPACK_FILENAME); + DBUG_ASSERT(cur_file == file_stack && cur_file->file == 0); + if (!(cur_file->file= + my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) + die("Could not open %s: errno = %d", buff, errno); + cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); + cur_file->lineno= 1; + break; + } case 'm': + { + static char buff[FN_REFLEN]; + if (!test_if_hard_path(argument)) { - static char buff[FN_REFLEN]; - if (!test_if_hard_path(argument)) - { - strxmov(buff, opt_basedir, argument, NullS); - argument= buff; - } - fn_format(buff, argument, "", "", 4); - timer_file= buff; - unlink(timer_file); /* Ignore error, may not exist */ - break; + strxmov(buff, opt_basedir, argument, NullS); + argument= buff; } + fn_format(buff, argument, "", "", MY_UNPACK_FILENAME); + timer_file= buff; + unlink(timer_file); /* Ignore error, may not exist */ + break; + } case 'p': if (argument) { @@ -2611,7 +3840,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), embedded_server_arg_count=1; embedded_server_args[0]= (char*) ""; } - if (embedded_server_arg_count == MAX_SERVER_ARGS-1 || + if (embedded_server_arg_count == MAX_EMBEDDED_SERVER_ARGS-1 || !(embedded_server_args[embedded_server_arg_count++]= my_strdup(argument, MYF(MY_FAE)))) { @@ -2619,8 +3848,7 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), } break; case 'F': - if (read_server_arguments(argument)) - die(NullS); + read_embedded_server_arguments(argument); break; case OPT_SKIP_SAFEMALLOC: #ifdef SAFEMALLOC @@ -2659,14 +3887,16 @@ int parse_args(int argc, char **argv) return 0; } -char* safe_str_append(char *buf, const char *str, int size) -{ - int i,c ; - for (i = 0; (c = *str++) && i < size - 1; i++) - *buf++ = c; - *buf = 0; - return buf; -} + +/* + Write the content of str into file + + SYNOPSIS + str_to_file + fname - name of file to truncate/create and write to + str - content to write to file + size - size of content witten to file +*/ void str_to_file(const char *fname, char *str, int size) { @@ -2675,38 +3905,213 @@ void str_to_file(const char *fname, char *str, int size) if (!test_if_hard_path(fname)) { strxmov(buff, opt_basedir, fname, NullS); - fname=buff; + fname= buff; } - fn_format(buff,fname,"","",4); - - if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC, - MYF(MY_WME | MY_FFNF))) < 0) + fn_format(buff, fname, "", "", MY_UNPACK_FILENAME); + + if ((fd= my_open(buff, O_WRONLY | O_CREAT | O_TRUNC, + MYF(MY_WME | MY_FFNF))) < 0) die("Could not open %s: errno = %d", buff, errno); if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP))) die("write failed"); my_close(fd, MYF(0)); } -void reject_dump(const char *record_file, char *buf, int size) + +void dump_result_to_reject_file(const char *record_file, char *buf, int size) { char reject_file[FN_REFLEN]; - str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size); + str_to_file(fn_format(reject_file, record_file, "", ".reject", + MY_REPLACE_EXT), + buf, size); +} + +void dump_result_to_log_file(const char *record_file, char *buf, int size) +{ + char log_file[FN_REFLEN]; + str_to_file(fn_format(log_file, record_file, "", ".log", + MY_REPLACE_EXT), + buf, size); +} + +void dump_progress(const char *record_file) +{ + char log_file[FN_REFLEN]; + str_to_file(fn_format(log_file, record_file, "", ".progress", + MY_REPLACE_EXT), + ds_progress.str, ds_progress.length); +} + +void check_regerr(my_regex_t* r, int err) +{ + char err_buf[1024]; + + if (err) + { + my_regerror(err,r,err_buf,sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } } -/* Append the string to ds, with optional replace */ +#ifdef __WIN__ -static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, - int len) +DYNAMIC_ARRAY patterns; + +/* + init_win_path_patterns + + DESCRIPTION + Setup string patterns that will be used to detect filenames that + needs to be converted from Win to Unix format + +*/ + +void init_win_path_patterns() { - if (glob_replace) + /* List of string patterns to match in order to find paths */ + const char* paths[] = { "$MYSQL_TEST_DIR", + "$MYSQL_TMP_DIR", + "./test/", 0 }; + int num_paths= 3; + int i; + char* p; + + DBUG_ENTER("init_win_path_patterns"); + + my_init_dynamic_array(&patterns, sizeof(const char*), 16, 16); + + /* Loop through all paths in the array */ + for (i= 0; i < num_paths; i++) { - len=(int) replace_strings(glob_replace, &out_buff, &out_length, val); - if (len == -1) - die("Out of memory in replace"); - val=out_buff; + VAR* v; + if (*(paths[i]) == '$') + { + v= var_get(paths[i], 0, 0, 0); + p= my_strdup(v->str_val, MYF(MY_FAE)); + } + else + p= my_strdup(paths[i], MYF(MY_FAE)); + + if (insert_dynamic(&patterns, (gptr) &p)) + die(NullS); + + DBUG_PRINT("info", ("p: %s", p)); + while (*p) + { + if (*p == '/') + *p='\\'; + p++; + } + } + DBUG_VOID_RETURN; +} + +void free_win_path_patterns() +{ + uint i= 0; + for (i=0 ; i < patterns.elements ; i++) + { + const char** pattern= dynamic_element(&patterns, i, const char**); + my_free((gptr) *pattern, MYF(0)); + } + delete_dynamic(&patterns); +} + +/* + fix_win_paths + + DESCRIPTION + Search the string 'val' for the patterns that are known to be + strings that contain filenames. Convert all \ to / in the + filenames that are found. + + Ex: + val = 'Error "c:\mysql\mysql-test\var\test\t1.frm" didn't exist' + => $MYSQL_TEST_DIR is found by strstr + => all \ from c:\mysql\m... until next space is converted into / +*/ + +void fix_win_paths(const char *val, int len) +{ + uint i; + char *p; + + DBUG_ENTER("fix_win_paths"); + for (i= 0; i < patterns.elements; i++) + { + const char** pattern= dynamic_element(&patterns, i, const char**); + DBUG_PRINT("info", ("pattern: %s", *pattern)); + if (strlen(*pattern) == 0) continue; + /* Search for the path in string */ + while ((p= strstr(val, *pattern))) + { + DBUG_PRINT("info", ("Found %s in val p: %s", *pattern, p)); + + while (*p && !my_isspace(charset_info, *p)) + { + if (*p == '\\') + *p= '/'; + p++; + } + DBUG_PRINT("info", ("Converted \\ to /, p: %s", p)); + } + } + DBUG_PRINT("exit", (" val: %s, len: %d", val, len)); + DBUG_VOID_RETURN; +} +#endif + + + +/* + Append the result for one field to the dynamic string ds +*/ + +void append_field(DYNAMIC_STRING *ds, uint col_idx, MYSQL_FIELD* field, + const char* val, ulonglong len, bool is_null) +{ + if (col_idx < max_replace_column && replace_column[col_idx]) + { + val= replace_column[col_idx]; + len= strlen(val); + } + else if (is_null) + { + val= "NULL"; + len= 4; + } +#ifdef __WIN__ + else if ((field->type == MYSQL_TYPE_DOUBLE || + field->type == MYSQL_TYPE_FLOAT ) && + field->decimals >= 31) + { + /* Convert 1.2e+018 to 1.2e+18 and 1.2e-018 to 1.2e-18 */ + char *start= strchr(val, 'e'); + if (start && strlen(start) >= 5 && + (start[1] == '-' || start[1] == '+') && start[2] == '0') + { + start+=2; /* Now points at first '0' */ + /* Move all chars after the first '0' one step left */ + memmove(start, start + 1, strlen(start)); + len--; + } + } +#endif + + if (!display_result_vertically) + { + if (col_idx) + dynstr_append_mem(ds, "\t", 1); + replace_dynstr_append_mem(ds, val, (int)len); + } + else + { + dynstr_append(ds, field->name); + dynstr_append_mem(ds, "\t", 1); + replace_dynstr_append_mem(ds, val, (int)len); + dynstr_append_mem(ds, "\n", 1); } - dynstr_append_mem(ds, val, len); } @@ -2715,676 +4120,97 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, Values may be converted with 'replace_column' */ -static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) +void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) { MYSQL_ROW row; uint num_fields= mysql_num_fields(res); - MYSQL_FIELD *fields= !display_result_vertically ? 0 : mysql_fetch_fields(res); - unsigned long *lengths; + MYSQL_FIELD *fields= mysql_fetch_fields(res); + ulong *lengths; + while ((row = mysql_fetch_row(res))) { uint i; lengths = mysql_fetch_lengths(res); for (i = 0; i < num_fields; i++) - { - const char *val= row[i]; - ulonglong len= lengths[i]; - - if (i < max_replace_column && replace_column[i]) - { - val= replace_column[i]; - len= strlen(val); - } - if (!val) - { - val= "NULL"; - len= 4; - } - if (!display_result_vertically) - { - if (i) - dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); - } - else - { - dynstr_append(ds, fields[i].name); - dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); - dynstr_append_mem(ds, "\n", 1); - } - } + append_field(ds, i, &fields[i], + (const char*)row[i], lengths[i], !row[i]); if (!display_result_vertically) dynstr_append_mem(ds, "\n", 1); } - free_replace_column(); } /* -* flags control the phased/stages of query execution to be performed -* if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on -* the result will be read - for regular query, both bits must be on + Append all results from ps execution to the dynamic string separated + with '\t'. Values may be converted with 'replace_column' */ -static int run_query_normal(MYSQL *mysql, struct st_query *q, int flags); -static int run_query_stmt (MYSQL *mysql, struct st_query *q, int flags); -static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds); -static int run_query_stmt_handle_error(char *query, struct st_query *q, - MYSQL_STMT *stmt, DYNAMIC_STRING *ds); -static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields, - DYNAMIC_STRING *ds); - -static int run_query(MYSQL *mysql, struct st_query *q, int flags) +void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, + MYSQL_FIELD *fields, uint num_fields) { - - /* - Try to find out if we can run this statement using the prepared - statement protocol. - - We don't have a mysql_stmt_send_execute() so we only handle - complete SEND+REAP. - - If it is a '?' in the query it may be a SQL level prepared - statement already and we can't do it twice - */ - - if (ps_protocol_enabled && disable_info && - (flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query)) - return run_query_stmt(mysql, q, flags); - return run_query_normal(mysql, q, flags); -} - - -static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) -{ - MYSQL_RES* res= 0; + MYSQL_BIND *bind; + my_bool *is_null; + ulong *length; uint i; - int error= 0, err= 0, counter= 0; - DYNAMIC_STRING *ds; - DYNAMIC_STRING ds_tmp; - DYNAMIC_STRING eval_query; - char* query; - int query_len, got_error_on_send= 0; - DBUG_ENTER("run_query_normal"); - DBUG_PRINT("enter",("flags: %d", flags)); - - if (q->type != Q_EVAL) - { - query = q->query; - query_len = strlen(query); - } - else - { - init_dynamic_string(&eval_query, "", 16384, 65536); - do_eval(&eval_query, q->query); - query = eval_query.str; - query_len = eval_query.length; - } - DBUG_PRINT("enter", ("query: '%-.60s'", query)); - if (q->record_file[0]) - { - init_dynamic_string(&ds_tmp, "", 16384, 65536); - ds = &ds_tmp; - } - else - ds= &ds_res; + /* Allocate array with bind structs, lengths and NULL flags */ + bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND), + MYF(MY_WME | MY_FAE | MY_ZEROFILL)); + length= (ulong*) my_malloc(num_fields * sizeof(ulong), + MYF(MY_WME | MY_FAE)); + is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool), + MYF(MY_WME | MY_FAE)); - if (flags & QUERY_SEND) + /* Allocate data for the result of each field */ + for (i= 0; i < num_fields; i++) { - got_error_on_send= mysql_send_query(mysql, query, query_len); - if (got_error_on_send && q->expected_errno[0].type == ERR_EMPTY) - die("unable to send query '%s' (mysql_errno=%d , errno=%d)", - query, mysql_errno(mysql), errno); + uint max_length= fields[i].max_length + 1; + bind[i].buffer_type= MYSQL_TYPE_STRING; + bind[i].buffer= (char *)my_malloc(max_length, MYF(MY_WME | MY_FAE)); + bind[i].buffer_length= max_length; + bind[i].is_null= &is_null[i]; + bind[i].length= &length[i]; + + DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %d", + i, bind[i].buffer_type, bind[i].buffer_length)); } - do + if (mysql_stmt_bind_result(stmt, bind)) + die("mysql_stmt_bind_result failed: %d: %s", + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + + while (mysql_stmt_fetch(stmt) == 0) { - if ((flags & QUERY_SEND) && !disable_query_log && !counter) - { - replace_dynstr_append_mem(ds,query, query_len); - dynstr_append_mem(ds, delimiter, delimiter_length); + for (i= 0; i < num_fields; i++) + append_field(ds, i, &fields[i], (const char *) bind[i].buffer, + *bind[i].length, *bind[i].is_null); + if (!display_result_vertically) dynstr_append_mem(ds, "\n", 1); - } - if (!(flags & QUERY_REAP)) - DBUG_RETURN(0); + } - if (got_error_on_send || - (!counter && (*mysql->methods->read_query_result)(mysql)) || - (!(last_result= res= mysql_store_result(mysql)) && - mysql_field_count(mysql))) - { - if (q->require_file) - { - abort_not_supported_test(); - } - if (q->abort_on_error) - die("query '%s' failed: %d: %s", query, - mysql_errno(mysql), mysql_error(mysql)); + if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA) + die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s", + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); - for (i=0 ; (uint) i < q->expected_errors ; i++) - { - if (((q->expected_errno[i].type == ERR_ERRNO) && - (q->expected_errno[i].code.errnum == mysql_errno(mysql))) || - ((q->expected_errno[i].type == ERR_SQLSTATE) && - (strcmp(q->expected_errno[i].code.sqlstate,mysql_sqlstate(mysql)) == 0))) - { - if (i == 0 && q->expected_errors == 1) - { - /* Only log error if there is one possible error */ - dynstr_append_mem(ds,"ERROR ",6); - replace_dynstr_append_mem(ds, mysql_sqlstate(mysql), - strlen(mysql_sqlstate(mysql))); - dynstr_append_mem(ds, ": ", 2); - replace_dynstr_append_mem(ds,mysql_error(mysql), - strlen(mysql_error(mysql))); - dynstr_append_mem(ds,"\n",1); - } - /* Don't log error if we may not get an error */ - else if (q->expected_errno[0].type == ERR_SQLSTATE || - (q->expected_errno[0].type == ERR_ERRNO && - q->expected_errno[0].code.errnum != 0)) - dynstr_append(ds,"Got one of the listed errors\n"); - goto end; /* Ok */ - } - } - DBUG_PRINT("info",("i: %d expected_errors: %d", i, - q->expected_errors)); - dynstr_append_mem(ds, "ERROR ",6); - replace_dynstr_append_mem(ds, mysql_sqlstate(mysql), - strlen(mysql_sqlstate(mysql))); - dynstr_append_mem(ds,": ",2); - replace_dynstr_append_mem(ds, mysql_error(mysql), - strlen(mysql_error(mysql))); - dynstr_append_mem(ds,"\n",1); - if (i) - { - if (q->expected_errno[0].type == ERR_ERRNO) - verbose_msg("query '%s' failed with wrong errno %d instead of %d...", - q->query, mysql_errno(mysql), q->expected_errno[0].code.errnum); - else - verbose_msg("query '%s' failed with wrong sqlstate %s instead of %s...", - q->query, mysql_sqlstate(mysql), q->expected_errno[0].code.sqlstate); - error= 1; - goto end; - } - verbose_msg("query '%s' failed: %d: %s", q->query, mysql_errno(mysql), - mysql_error(mysql)); - /* - if we do not abort on error, failure to run the query does - not fail the whole test case - */ - goto end; - - } - - if (handle_no_error(q)) - { - error= 1; - goto end; - } - - if (!disable_result_log) - { - ulong affected_rows; /* Ok to be undef if 'disable_info' is set */ - LINT_INIT(affected_rows); - - if (res) - { - MYSQL_FIELD *field= mysql_fetch_fields(res); - uint num_fields= mysql_num_fields(res); - - if (display_metadata) - run_query_display_metadata(field, num_fields, ds); - - if (!display_result_vertically) - { - for (i = 0; i < num_fields; i++) - { - if (i) - dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, field[i].name, - strlen(field[i].name)); - } - dynstr_append_mem(ds, "\n", 1); - } - append_result(ds, res); - } - - /* - Need to call mysql_affected_rows() before the new - query to find the warnings - */ - if (!disable_info) - affected_rows= (ulong)mysql_affected_rows(mysql); - - /* Add all warnings to the result */ - if (!disable_warnings && mysql_warning_count(mysql)) - { - MYSQL_RES *warn_res=0; - uint count= mysql_warning_count(mysql); - if (!mysql_real_query(mysql, "SHOW WARNINGS", 13)) - { - warn_res= mysql_store_result(mysql); - } - if (!warn_res) - die("Warning count is %u but didn't get any warnings\n", - count); - else - { - dynstr_append_mem(ds, "Warnings:\n", 10); - append_result(ds, warn_res); - mysql_free_result(warn_res); - } - } - if (!disable_info) - { - char buf[40]; - sprintf(buf,"affected rows: %lu\n", affected_rows); - dynstr_append(ds, buf); - if (mysql_info(mysql)) - { - dynstr_append(ds, "info: "); - dynstr_append(ds, mysql_info(mysql)); - dynstr_append_mem(ds, "\n", 1); - } - } - } - - if (record) - { - if (!q->record_file[0] && !result_file) - die("Missing result file"); - if (!result_file) - str_to_file(q->record_file, ds->str, ds->length); - } - else if (q->record_file[0]) - { - error = check_result(ds, q->record_file, q->require_file); - } - if (res) - mysql_free_result(res); - last_result= 0; - counter++; - } while (!(err= mysql_next_result(mysql))); - if (err >= 1) - mysql_error(mysql); - -end: - free_replace(); - last_result=0; - if (ds == &ds_tmp) - dynstr_free(&ds_tmp); - if (q->type == Q_EVAL) - dynstr_free(&eval_query); - - /* - We save the return code (mysql_errno(mysql)) from the last call sent - to the server into the mysqltest builtin variable $mysql_errno. This - variable then can be used from the test case itself. - */ - var_set_errno(mysql_errno(mysql)); - DBUG_RETURN(error); + for (i= 0; i < num_fields; i++) + { + /* Free data for output */ + my_free((gptr)bind[i].buffer, MYF(MY_WME | MY_FAE)); + } + /* Free array with bind structs, lengths and NULL flags */ + my_free((gptr)bind , MYF(MY_WME | MY_FAE)); + my_free((gptr)length , MYF(MY_WME | MY_FAE)); + my_free((gptr)is_null , MYF(MY_WME | MY_FAE)); } -/****************************************************************************\ - * If --ps-protocol run ordinary statements using prepared statemnt C API -\****************************************************************************/ - /* - We don't have a mysql_stmt_send_execute() so we only handle - complete SEND+REAP + Append metadata for fields to output */ -static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) -{ - int error= 0; /* Function return code if "goto end;" */ - int err; /* Temporary storage of return code from calls */ - int query_len, got_error_on_execute; - uint num_rows; - char *query; - MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */ - DYNAMIC_STRING *ds; - DYNAMIC_STRING ds_tmp; - DYNAMIC_STRING eval_query; - MYSQL_STMT *stmt; - DBUG_ENTER("run_query_stmt"); - - /* - We must allocate a new stmt for each query in this program becasue this - may be a new connection. - */ - if (!(stmt= mysql_stmt_init(mysql))) - die("unable init stmt structure"); - - if (q->type != Q_EVAL) - { - query= q->query; - query_len= strlen(query); - } - else - { - init_dynamic_string(&eval_query, "", 16384, 65536); - do_eval(&eval_query, q->query); - query= eval_query.str; - query_len= eval_query.length; - } - DBUG_PRINT("query", ("'%-.60s'", query)); - - if (q->record_file[0]) - { - init_dynamic_string(&ds_tmp, "", 16384, 65536); - ds= &ds_tmp; - } - else - ds= &ds_res; - - /* Store the query into the output buffer if not disabled */ - if (!disable_query_log) - { - replace_dynstr_append_mem(ds,query, query_len); - dynstr_append_mem(ds, delimiter, delimiter_length); - dynstr_append_mem(ds, "\n", 1); - } - - /* - We use the prepared statement interface but there is actually no - '?' in the query. If unpreparable we fall back to use normal - C API. - */ - if ((err= mysql_stmt_prepare(stmt, query, query_len)) == CR_NO_PREPARE_STMT) - return run_query_normal(mysql, q, flags); - - if (err != 0) - { - if (q->abort_on_error) - { - die("query '%s' failed: %d: %s", query, - mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); - } - else - { - /* - Preparing is part of normal execution and some errors may be expected - */ - error= run_query_stmt_handle_error(query, q, stmt, ds); - goto end; - } - } - - /* We may have got warnings already, collect them if any */ - /* FIXME we only want this if the statement succeeds I think */ - run_query_stmt_handle_warnings(mysql, ds); - - /* - No need to call mysql_stmt_bind_param() because we have no - parameter markers. - - To optimize performance we use a global 'stmt' that is initiated - once. A new prepare will implicitely close the old one. When we - terminate we will lose the connection, this also closes the last - prepared statement. - */ - - if ((got_error_on_execute= mysql_stmt_execute(stmt)) != 0) /* 0 == Success */ - { - if (q->abort_on_error) - { - /* We got an error, unexpected */ - die("unable to execute statement '%s': " - "%s (mysql_stmt_errno=%d returned=%d)", - query, mysql_stmt_error(stmt), - mysql_stmt_errno(stmt), got_error_on_execute); - } - else - { - /* We got an error, maybe expected */ - error= run_query_stmt_handle_error(query, q, stmt, ds); - goto end; - } - } - - /* - We instruct that we want to update the "max_length" field in - mysql_stmt_store_result(), this is our only way to know how much - buffer to allocate for result data - */ - { - my_bool one= 1; - if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, - (void*) &one) != 0) - die("unable to set stmt attribute " - "'STMT_ATTR_UPDATE_MAX_LENGTH': %s (returned=%d)", - query, err); - } - - /* - If we got here the statement succeeded and was expected to do so, - get data. Note that this can still give errors found during execution! - */ - if ((err= mysql_stmt_store_result(stmt)) != 0) - { - if (q->abort_on_error) - { - /* We got an error, unexpected */ - die("unable to execute statement '%s': " - "%s (mysql_stmt_errno=%d returned=%d)", - query, mysql_stmt_error(stmt), - mysql_stmt_errno(stmt), got_error_on_execute); - } - else - { - /* We got an error, maybe expected */ - error= run_query_stmt_handle_error(query, q, stmt, ds); - goto end; - } - } - - /* If we got here the statement was both executed and read succeesfully */ - if (handle_no_error(q)) - { - error= 1; - goto end; - } - - num_rows= mysql_stmt_num_rows(stmt); - - /* - Not all statements creates a result set. If there is one we can - now create another normal result set that contains the meta - data. This set can be handled almost like any other non prepared - statement result set. - */ - if (!disable_result_log && ((res= mysql_stmt_result_metadata(stmt)) != NULL)) - { - /* Take the column count from meta info */ - MYSQL_FIELD *field= mysql_fetch_fields(res); - uint num_fields= mysql_num_fields(res); - - /* FIXME check error from the above? */ - - if (display_metadata) - run_query_display_metadata(field, num_fields, ds); - - if (!display_result_vertically) - { - /* Display the table heading with the names tab separated */ - uint col_idx; - for (col_idx= 0; col_idx < num_fields; col_idx++) - { - if (col_idx) - dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, field[col_idx].name, - strlen(field[col_idx].name)); - } - dynstr_append_mem(ds, "\n", 1); - } - - /* Now we are to put the real result into the output buffer */ - /* FIXME when it works, create function append_stmt_result() */ - { - MYSQL_BIND *bind; - my_bool *is_null; - unsigned long *length; - /* FIXME we don't handle vertical display ..... */ - uint col_idx, row_idx; - - /* Allocate array with bind structs, lengths and NULL flags */ - bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND), - MYF(MY_WME | MY_FAE)); - length= (unsigned long*) my_malloc(num_fields * sizeof(unsigned long), - MYF(MY_WME | MY_FAE)); - is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool), - MYF(MY_WME | MY_FAE)); - - for (col_idx= 0; col_idx < num_fields; col_idx++) - { - /* Allocate data for output */ - /* - FIXME it may be a bug that for non string/blob types - 'max_length' is 0, should try out 'length' in that case - */ - uint max_length= max(field[col_idx].max_length + 1, 1024); - char *str_data= (char *) my_malloc(max_length, MYF(MY_WME | MY_FAE)); - - bind[col_idx].buffer_type= MYSQL_TYPE_STRING; - bind[col_idx].buffer= (char *)str_data; - bind[col_idx].buffer_length= max_length; - bind[col_idx].is_null= &is_null[col_idx]; - bind[col_idx].length= &length[col_idx]; - } - - /* Fill in the data into the structures created above */ - if ((err= mysql_stmt_bind_result(stmt, bind)) != 0) - die("unable to bind result to statement '%s': " - "%s (mysql_stmt_errno=%d returned=%d)", - query, - mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); - - /* Read result from each row */ - for (row_idx= 0; row_idx < num_rows; row_idx++) - { - if ((err= mysql_stmt_fetch(stmt)) != 0) - die("unable to fetch all rows from statement '%s': " - "%s (mysql_stmt_errno=%d returned=%d)", - query, - mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); - - /* Read result from each column */ - for (col_idx= 0; col_idx < num_fields; col_idx++) - { - const char *val; - ulonglong len; - if (col_idx < max_replace_column && replace_column[col_idx]) - { - val= replace_column[col_idx]; - len= strlen(val); - } - else if (*bind[col_idx].is_null) - { - val= "NULL"; - len= 4; - } - else - { - /* FIXME is string terminated? */ - val= (const char *) bind[col_idx].buffer; - len= *bind[col_idx].length; - } - if (!display_result_vertically) - { - if (col_idx) /* No tab before first col */ - dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); - } - else - { - dynstr_append(ds, field[col_idx].name); - dynstr_append_mem(ds, "\t", 1); - replace_dynstr_append_mem(ds, val, len); - dynstr_append_mem(ds, "\n", 1); - } - } - if (!display_result_vertically) - dynstr_append_mem(ds, "\n", 1); - } - - if ((err= mysql_stmt_fetch(stmt)) != MYSQL_NO_DATA) - die("fetch didn't end with MYSQL_NO_DATA from statement " - "'%s': %s (mysql_stmt_errno=%d returned=%d)", - query, - mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); - - free_replace_column(); - - for (col_idx= 0; col_idx < num_fields; col_idx++) - { - /* Free data for output */ - my_free((gptr)bind[col_idx].buffer, MYF(MY_WME | MY_FAE)); - } - /* Free array with bind structs, lengths and NULL flags */ - my_free((gptr)bind , MYF(MY_WME | MY_FAE)); - my_free((gptr)length , MYF(MY_WME | MY_FAE)); - my_free((gptr)is_null , MYF(MY_WME | MY_FAE)); - } - - /* Add all warnings to the result */ - run_query_stmt_handle_warnings(mysql, ds); - - if (!disable_info) - { - char buf[40]; - sprintf(buf,"affected rows: %lu\n",(ulong) mysql_affected_rows(mysql)); - dynstr_append(ds, buf); - if (mysql_info(mysql)) - { - dynstr_append(ds, "info: "); - dynstr_append(ds, mysql_info(mysql)); - dynstr_append_mem(ds, "\n", 1); - } - } - } - run_query_stmt_handle_warnings(mysql, ds); - - if (record) - { - if (!q->record_file[0] && !result_file) - die("Missing result file"); - if (!result_file) - str_to_file(q->record_file, ds->str, ds->length); - } - else if (q->record_file[0]) - { - error= check_result(ds, q->record_file, q->require_file); - } - if (res) - mysql_free_result(res); /* Free normal result set with meta data */ - last_result= 0; /* FIXME have no idea what this is about... */ - - if (err >= 1) - mysql_error(mysql); /* FIXME strange, has no effect... */ - -end: - free_replace(); - last_result=0; - if (ds == &ds_tmp) - dynstr_free(&ds_tmp); - if (q->type == Q_EVAL) - dynstr_free(&eval_query); - var_set_errno(mysql_stmt_errno(stmt)); - mysql_stmt_close(stmt); - DBUG_RETURN(error); -} - - -/****************************************************************************\ - * Broken out sub functions to run_query_stmt() -\****************************************************************************/ - -static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields, - DYNAMIC_STRING *ds) +void append_metadata(DYNAMIC_STRING *ds, + MYSQL_FIELD *field, + uint num_fields) { MYSQL_FIELD *field_end; dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t" @@ -3395,147 +4221,360 @@ static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields, field < field_end ; field++) { - char buff[22]; dynstr_append_mem(ds, field->catalog, - field->catalog_length); + field->catalog_length); dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, field->db, field->db_length); dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, field->org_table, - field->org_table_length); + field->org_table_length); dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, field->table, - field->table_length); + field->table_length); dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, field->org_name, - field->org_name_length); + field->org_name_length); dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, field->name, field->name_length); dynstr_append_mem(ds, "\t", 1); - int10_to_str((int) field->type, buff, 10); - dynstr_append(ds, buff); + replace_dynstr_append_uint(ds, field->type); dynstr_append_mem(ds, "\t", 1); - longlong10_to_str((unsigned int) field->length, buff, 10); - dynstr_append(ds, buff); + replace_dynstr_append_uint(ds, field->length); dynstr_append_mem(ds, "\t", 1); - longlong10_to_str((unsigned int) field->max_length, buff, 10); - dynstr_append(ds, buff); + replace_dynstr_append_uint(ds, field->max_length); dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ? "N" : "Y"), 1); dynstr_append_mem(ds, "\t", 1); - - int10_to_str((int) field->flags, buff, 10); - dynstr_append(ds, buff); + replace_dynstr_append_uint(ds, field->flags); dynstr_append_mem(ds, "\t", 1); - int10_to_str((int) field->decimals, buff, 10); - dynstr_append(ds, buff); + replace_dynstr_append_uint(ds, field->decimals); dynstr_append_mem(ds, "\t", 1); - int10_to_str((int) field->charsetnr, buff, 10); - dynstr_append(ds, buff); + replace_dynstr_append_uint(ds, field->charsetnr); dynstr_append_mem(ds, "\n", 1); } } -static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds) +/* + Append affected row count and other info to output +*/ + +void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows, + const char *info) +{ + char buf[40], buff2[21]; + sprintf(buf,"affected rows: %s\n", llstr(affected_rows, buff2)); + dynstr_append(ds, buf); + if (info) + { + dynstr_append(ds, "info: "); + dynstr_append(ds, info); + dynstr_append_mem(ds, "\n", 1); + } +} + + +/* + Display the table headings with the names tab separated +*/ + +void append_table_headings(DYNAMIC_STRING *ds, + MYSQL_FIELD *field, + uint num_fields) +{ + uint col_idx; + for (col_idx= 0; col_idx < num_fields; col_idx++) + { + if (col_idx) + dynstr_append_mem(ds, "\t", 1); + replace_dynstr_append(ds, field[col_idx].name); + } + dynstr_append_mem(ds, "\n", 1); +} + +/* + Fetch warnings from server and append to ds + + RETURN VALUE + Number of warnings appended to ds +*/ + +int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql) { uint count; - DBUG_ENTER("run_query_stmt_handle_warnings"); + MYSQL_RES *warn_res; + DBUG_ENTER("append_warnings"); - if (!disable_warnings && (count= mysql_warning_count(mysql))) + if (!(count= mysql_warning_count(mysql))) + DBUG_RETURN(0); + + /* + If one day we will support execution of multi-statements + through PS API we should not issue SHOW WARNINGS until + we have not read all results... + */ + DBUG_ASSERT(!mysql_more_results(mysql)); + + if (mysql_real_query(mysql, "SHOW WARNINGS", 13)) + die("Error running query \"SHOW WARNINGS\": %s", mysql_error(mysql)); + + if (!(warn_res= mysql_store_result(mysql))) + die("Warning count is %u but didn't get any warnings", + count); + + append_result(ds, warn_res); + mysql_free_result(warn_res); + + DBUG_PRINT("warnings", ("%s", ds->str)); + + DBUG_RETURN(count); +} + + + +/* + Run query using MySQL C API + + SYNPOSIS + run_query_normal + mysql - mysql handle + command - currrent command pointer + flags -flags indicating wheter to SEND and/or REAP + query - query string to execute + query_len - length query string to execute + ds - output buffer wherte to store result form query + + RETURN VALUE + error - function will not return +*/ + +void run_query_normal(MYSQL *mysql, struct st_command *command, + int flags, char *query, int query_len, + DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings) +{ + MYSQL_RES *res= 0; + int err= 0, counter= 0; + DBUG_ENTER("run_query_normal"); + DBUG_PRINT("enter",("flags: %d", flags)); + DBUG_PRINT("enter", ("query: '%-.60s'", query)); + + if (flags & QUERY_SEND_FLAG) { - if (mysql_real_query(mysql, "SHOW WARNINGS", 13) == 0) + /* + Send the query + */ + if (mysql_send_query(mysql, query, query_len)) { - MYSQL_RES *warn_res= mysql_store_result(mysql); - if (!warn_res) - die("Warning count is %u but didn't get any warnings\n", - count); - else - { - dynstr_append_mem(ds, "Warnings:\n", 10); - append_result(ds, warn_res); - mysql_free_result(warn_res); - } + handle_error(command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), ds); + goto end; } } + + if (!(flags & QUERY_REAP_FLAG)) + DBUG_VOID_RETURN; + + do + { + /* + When on first result set, call mysql_read_query_result to retrieve + answer to the query sent earlier + */ + if ((counter==0) && mysql_read_query_result(mysql)) + { + handle_error(command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), ds); + goto end; + + } + + /* + Store the result. If res is NULL, use mysql_field_count to + determine if that was expected + */ + if (!(res= mysql_store_result(mysql)) && mysql_field_count(mysql)) + { + handle_error(command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), ds); + goto end; + } + + if (!disable_result_log) + { + ulonglong affected_rows; /* Ok to be undef if 'disable_info' is set */ + LINT_INIT(affected_rows); + + if (res) + { + MYSQL_FIELD *fields= mysql_fetch_fields(res); + uint num_fields= mysql_num_fields(res); + + if (display_metadata) + append_metadata(ds, fields, num_fields); + + if (!display_result_vertically) + append_table_headings(ds, fields, num_fields); + + append_result(ds, res); + } + + /* + Need to call mysql_affected_rows() before the "new" + query to find the warnings + */ + if (!disable_info) + affected_rows= mysql_affected_rows(mysql); + + /* + Add all warnings to the result. We can't do this if we are in + the middle of processing results from multi-statement, because + this will break protocol. + */ + if (!disable_warnings && !mysql_more_results(mysql)) + { + if (append_warnings(ds_warnings, mysql) || ds_warnings->length) + { + dynstr_append_mem(ds, "Warnings:\n", 10); + dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length); + } + } + + if (!disable_info) + append_info(ds, affected_rows, mysql_info(mysql)); + } + + if (res) + mysql_free_result(res); + counter++; + } while (!(err= mysql_next_result(mysql))); + if (err > 0) + { + /* We got an error from mysql_next_result, maybe expected */ + handle_error(command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), ds); + goto end; + } + DBUG_ASSERT(err == -1); /* Successful and there are no more results */ + + /* If we come here the query is both executed and read successfully */ + handle_no_error(command); + +end: + + /* + We save the return code (mysql_errno(mysql)) from the last call sent + to the server into the mysqltest builtin variable $mysql_errno. This + variable then can be used from the test case itself. + */ + var_set_errno(mysql_errno(mysql)); DBUG_VOID_RETURN; } -static int run_query_stmt_handle_error(char *query, struct st_query *q, - MYSQL_STMT *stmt, DYNAMIC_STRING *ds) +/* + Handle errors which occurred during execution + + SYNOPSIS + handle_error() + q - query context + err_errno - error number + err_error - error message + err_sqlstate - sql state + ds - dynamic string which is used for output buffer + + NOTE + If there is an unexpected error this function will abort mysqltest + immediately. + + RETURN VALUE + error - function will not return +*/ + +void handle_error(struct st_command *command, + unsigned int err_errno, const char *err_error, + const char *err_sqlstate, DYNAMIC_STRING *ds) { - if (q->require_file) /* FIXME don't understand this one */ + uint i; + + DBUG_ENTER("handle_error"); + + if (command->require_file) { - abort_not_supported_test(); + /* + The query after a "--require" failed. This is fine as long the server + returned a valid reponse. Don't allow 2013 or 2006 to trigger an + abort_not_supported_test + */ + if (err_errno == CR_SERVER_LOST || + err_errno == CR_SERVER_GONE_ERROR) + die("require query '%s' failed: %d: %s", command->query, err_errno, err_error); + + /* Abort the run of this test, pass the failed query as reason */ + abort_not_supported_test("Query '%s' failed, required functionality" \ + "not supported", command->query); } - if (q->abort_on_error) - die("query '%s' failed: %d: %s", query, - mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); - else - { - int i; + if (command->abort_on_error) + die("query '%s' failed: %d: %s", command->query, err_errno, err_error); - for (i=0 ; (uint) i < q->expected_errors ; i++) + DBUG_PRINT("info", ("expected_errors.count: %d", + command->expected_errors.count)); + for (i= 0 ; (uint) i < command->expected_errors.count ; i++) + { + if (((command->expected_errors.err[i].type == ERR_ERRNO) && + (command->expected_errors.err[i].code.errnum == err_errno)) || + ((command->expected_errors.err[i].type == ERR_SQLSTATE) && + (strcmp(command->expected_errors.err[i].code.sqlstate, + err_sqlstate) == 0))) { - if (((q->expected_errno[i].type == ERR_ERRNO) && - (q->expected_errno[i].code.errnum == mysql_stmt_errno(stmt))) || - ((q->expected_errno[i].type == ERR_SQLSTATE) && - (strcmp(q->expected_errno[i].code.sqlstate, - mysql_stmt_sqlstate(stmt)) == 0))) + if (!disable_result_log) { - if (i == 0 && q->expected_errors == 1) + if (command->expected_errors.count == 1) { /* Only log error if there is one possible error */ - dynstr_append_mem(ds,"ERROR ",6); - replace_dynstr_append_mem(ds, mysql_stmt_sqlstate(stmt), - strlen(mysql_stmt_sqlstate(stmt))); + dynstr_append_mem(ds, "ERROR ", 6); + replace_dynstr_append(ds, err_sqlstate); dynstr_append_mem(ds, ": ", 2); - replace_dynstr_append_mem(ds,mysql_stmt_error(stmt), - strlen(mysql_stmt_error(stmt))); + replace_dynstr_append(ds, err_error); dynstr_append_mem(ds,"\n",1); } /* Don't log error if we may not get an error */ - else if (q->expected_errno[0].type == ERR_SQLSTATE || - (q->expected_errno[0].type == ERR_ERRNO && - q->expected_errno[0].code.errnum != 0)) + else if (command->expected_errors.err[0].type == ERR_SQLSTATE || + (command->expected_errors.err[0].type == ERR_ERRNO && + command->expected_errors.err[0].code.errnum != 0)) dynstr_append(ds,"Got one of the listed errors\n"); - return 0; /* Ok */ } + /* OK */ + DBUG_VOID_RETURN; } - DBUG_PRINT("info",("i: %d expected_errors: %d", i, - q->expected_errors)); - dynstr_append_mem(ds, "ERROR ",6); - replace_dynstr_append_mem(ds, mysql_stmt_sqlstate(stmt), - strlen(mysql_stmt_sqlstate(stmt))); - dynstr_append_mem(ds,": ",2); - replace_dynstr_append_mem(ds, mysql_stmt_error(stmt), - strlen(mysql_stmt_error(stmt))); - dynstr_append_mem(ds,"\n",1); - if (i) - { - if (q->expected_errno[0].type == ERR_ERRNO) - verbose_msg("query '%s' failed with wrong errno %d instead of %d...", - q->query, mysql_stmt_errno(stmt), - q->expected_errno[0].code.errnum); - else - verbose_msg("query '%s' failed with wrong sqlstate %s instead of %s...", - q->query, mysql_stmt_sqlstate(stmt), - q->expected_errno[0].code.sqlstate); - return 1; /* Error */ - } - verbose_msg("query '%s' failed: %d: %s", q->query, mysql_stmt_errno(stmt), - mysql_stmt_error(stmt)); - /* - if we do not abort on error, failure to run the query does - not fail the whole test case - */ - return 0; } - return 0; + DBUG_PRINT("info",("i: %d expected_errors: %d", i, + command->expected_errors)); + + if (!disable_result_log) + { + dynstr_append_mem(ds, "ERROR ",6); + replace_dynstr_append(ds, err_sqlstate); + dynstr_append_mem(ds, ": ", 2); + replace_dynstr_append(ds, err_error); + dynstr_append_mem(ds, "\n", 1); + } + + if (i) + { + if (command->expected_errors.err[0].type == ERR_ERRNO) + die("query '%s' failed with wrong errno %d: '%s', instead of %d...", + command->query, err_errno, err_error, + command->expected_errors.err[0].code.errnum); + else + die("query '%s' failed with wrong sqlstate %s: '%s', instead of %s...", + command->query, err_sqlstate, err_error, + command->expected_errors.err[0].code.sqlstate); + } + + DBUG_VOID_RETURN; } @@ -3543,44 +4582,518 @@ static int run_query_stmt_handle_error(char *query, struct st_query *q, Handle absence of errors after execution SYNOPSIS - handle_no_error() - q - context of query + handle_no_error() + q - context of query RETURN VALUE - 0 - OK - 1 - Some error was expected from this query. + error - function will not return */ -static int handle_no_error(struct st_query *q) +void handle_no_error(struct st_command *command) { DBUG_ENTER("handle_no_error"); - if (q->expected_errno[0].type == ERR_ERRNO && - q->expected_errno[0].code.errnum != 0) + if (command->expected_errors.err[0].type == ERR_ERRNO && + command->expected_errors.err[0].code.errnum != 0) { /* Error code we wanted was != 0, i.e. not an expected success */ - verbose_msg("query '%s' succeeded - should have failed with errno %d...", - q->query, q->expected_errno[0].code.errnum); - DBUG_RETURN(1); + die("query '%s' succeeded - should have failed with errno %d...", + command->query, command->expected_errors.err[0].code.errnum); } - else if (q->expected_errno[0].type == ERR_SQLSTATE && - strcmp(q->expected_errno[0].code.sqlstate,"00000") != 0) + else if (command->expected_errors.err[0].type == ERR_SQLSTATE && + strcmp(command->expected_errors.err[0].code.sqlstate,"00000") != 0) { /* SQLSTATE we wanted was != "00000", i.e. not an expected success */ - verbose_msg("query '%s' succeeded - should have failed with sqlstate %s...", - q->query, q->expected_errno[0].code.sqlstate); - DBUG_RETURN(1); + die("query '%s' succeeded - should have failed with sqlstate %s...", + command->query, command->expected_errors.err[0].code.sqlstate); } - DBUG_RETURN(0); + DBUG_VOID_RETURN; } -/****************************************************************************\ - * Functions to match SQL statements that can be prepared -\****************************************************************************/ -static void ps_init_re(void) +/* + Run query using prepared statement C API + + SYNPOSIS + run_query_stmt + mysql - mysql handle + command - currrent command pointer + query - query string to execute + query_len - length query string to execute + ds - output buffer where to store result form query + + RETURN VALUE + error - function will not return +*/ + +void run_query_stmt(MYSQL *mysql, struct st_command *command, + char *query, int query_len, DYNAMIC_STRING *ds, + DYNAMIC_STRING *ds_warnings) { + MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */ + MYSQL_STMT *stmt; + DYNAMIC_STRING ds_prepare_warnings; + DYNAMIC_STRING ds_execute_warnings; + DBUG_ENTER("run_query_stmt"); + DBUG_PRINT("query", ("'%-.60s'", query)); + + /* + Init a new stmt if it's not already one created for this connection + */ + if(!(stmt= cur_con->stmt)) + { + if (!(stmt= mysql_stmt_init(mysql))) + die("unable to init stmt structure"); + cur_con->stmt= stmt; + } + + /* Init dynamic strings for warnings */ + if (!disable_warnings) + { + init_dynamic_string(&ds_prepare_warnings, NULL, 0, 256); + init_dynamic_string(&ds_execute_warnings, NULL, 0, 256); + } + + /* + Prepare the query + */ + if (mysql_stmt_prepare(stmt, query, query_len)) + { + handle_error(command, mysql_stmt_errno(stmt), + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + goto end; + } + + /* + Get the warnings from mysql_stmt_prepare and keep them in a + separate string + */ + if (!disable_warnings) + append_warnings(&ds_prepare_warnings, mysql); + + /* + No need to call mysql_stmt_bind_param() because we have no + parameter markers. + */ + +#if MYSQL_VERSION_ID >= 50000 + if (cursor_protocol_enabled) + { + /* + Use cursor when retrieving result + */ + ulong type= CURSOR_TYPE_READ_ONLY; + if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type)) + die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s", + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + } +#endif + + /* + Execute the query + */ + if (mysql_stmt_execute(stmt)) + { + handle_error(command, mysql_stmt_errno(stmt), + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + goto end; + } + + /* + When running in cursor_protocol get the warnings from execute here + and keep them in a separate string for later. + */ + if (cursor_protocol_enabled && !disable_warnings) + append_warnings(&ds_execute_warnings, mysql); + + /* + We instruct that we want to update the "max_length" field in + mysql_stmt_store_result(), this is our only way to know how much + buffer to allocate for result data + */ + { + my_bool one= 1; + if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one)) + die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s", + mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); + } + + /* + If we got here the statement succeeded and was expected to do so, + get data. Note that this can still give errors found during execution! + */ + if (mysql_stmt_store_result(stmt)) + { + handle_error(command, mysql_stmt_errno(stmt), + mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds); + goto end; + } + + /* If we got here the statement was both executed and read successfully */ + handle_no_error(command); + if (!disable_result_log) + { + /* + Not all statements creates a result set. If there is one we can + now create another normal result set that contains the meta + data. This set can be handled almost like any other non prepared + statement result set. + */ + if ((res= mysql_stmt_result_metadata(stmt)) != NULL) + { + /* Take the column count from meta info */ + MYSQL_FIELD *fields= mysql_fetch_fields(res); + uint num_fields= mysql_num_fields(res); + + if (display_metadata) + append_metadata(ds, fields, num_fields); + + if (!display_result_vertically) + append_table_headings(ds, fields, num_fields); + + append_stmt_result(ds, stmt, fields, num_fields); + + mysql_free_result(res); /* Free normal result set with meta data */ + + /* Clear prepare warnings */ + dynstr_set(&ds_prepare_warnings, NULL); + } + else + { + /* + This is a query without resultset + */ + } + + if (!disable_warnings) + { + /* Get the warnings from execute */ + + /* Append warnings to ds - if there are any */ + if (append_warnings(&ds_execute_warnings, mysql) || + ds_execute_warnings.length || + ds_prepare_warnings.length || + ds_warnings->length) + { + dynstr_append_mem(ds, "Warnings:\n", 10); + if (ds_warnings->length) + dynstr_append_mem(ds, ds_warnings->str, + ds_warnings->length); + if (ds_prepare_warnings.length) + dynstr_append_mem(ds, ds_prepare_warnings.str, + ds_prepare_warnings.length); + if (ds_execute_warnings.length) + dynstr_append_mem(ds, ds_execute_warnings.str, + ds_execute_warnings.length); + } + } + + if (!disable_info) + append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql)); + + } + +end: + if (!disable_warnings) + { + dynstr_free(&ds_prepare_warnings); + dynstr_free(&ds_execute_warnings); + } + + /* + We save the return code (mysql_stmt_errno(stmt)) from the last call sent + to the server into the mysqltest builtin variable $mysql_errno. This + variable then can be used from the test case itself. + */ + + var_set_errno(mysql_stmt_errno(stmt)); +#ifndef BUG15518_FIXED + mysql_stmt_close(stmt); + cur_con->stmt= NULL; +#endif + DBUG_VOID_RETURN; +} + + + +/* + Create a util connection if one does not already exists + and use that to run the query + This is done to avoid implict commit when creating/dropping objects such + as view, sp etc. +*/ + +int util_query(MYSQL* org_mysql, const char* query){ + + MYSQL* mysql; + DBUG_ENTER("util_query"); + + if(!(mysql= cur_con->util_mysql)) + { + DBUG_PRINT("info", ("Creating util_mysql")); + if (!(mysql= mysql_init(mysql))) + die("Failed in mysql_init()"); + + safe_connect(mysql, "util", org_mysql->host, org_mysql->user, + org_mysql->passwd, org_mysql->db, org_mysql->port, + org_mysql->unix_socket); + + cur_con->util_mysql= mysql; + } + + return mysql_query(mysql, query); +} + + + +/* + Run query + + flags control the phased/stages of query execution to be performed + if QUERY_SEND_FLAG bit is on, the query will be sent. If QUERY_REAP_FLAG + is on the result will be read - for regular query, both bits must be on + + SYNPOSIS + run_query + mysql - mysql handle + command - currrent command pointer + +*/ + +void run_query(MYSQL *mysql, struct st_command *command, int flags) +{ + DYNAMIC_STRING *ds; + DYNAMIC_STRING ds_result; + DYNAMIC_STRING ds_warnings; + DYNAMIC_STRING eval_query; + char *query; + int query_len; + my_bool view_created= 0, sp_created= 0; + my_bool complete_query= ((flags & QUERY_SEND_FLAG) && + (flags & QUERY_REAP_FLAG)); + + init_dynamic_string(&ds_warnings, NULL, 0, 256); + + /* + Evaluate query if this is an eval command + */ + if (command->type == Q_EVAL) + { + init_dynamic_string(&eval_query, "", command->query_len+256, 1024); + do_eval(&eval_query, command->query, command->end, FALSE); + query = eval_query.str; + query_len = eval_query.length; + } + else + { + query = command->query; + query_len = strlen(query); + } + + /* + When command->record_file is set the output of _this_ query + should be compared with an already existing file + Create a temporary dynamic string to contain the output from + this query. + */ + if (command->record_file[0]) + { + init_dynamic_string(&ds_result, "", 1024, 1024); + ds= &ds_result; + } + else + ds= &ds_res; + + /* + Log the query into the output buffer + */ + if (!disable_query_log && (flags & QUERY_SEND_FLAG)) + { + replace_dynstr_append_mem(ds, query, query_len); + dynstr_append_mem(ds, delimiter, delimiter_length); + dynstr_append_mem(ds, "\n", 1); + } + + if (view_protocol_enabled && + complete_query && + match_re(&view_re, query)) + { + /* + Create the query as a view. + Use replace since view can exist from a failed mysqltest run + */ + DYNAMIC_STRING query_str; + init_dynamic_string(&query_str, + "CREATE OR REPLACE VIEW mysqltest_tmp_v AS ", + query_len+64, 256); + dynstr_append_mem(&query_str, query, query_len); + if (util_query(mysql, query_str.str)) + { + /* + Failed to create the view, this is not fatal + just run the query the normal way + */ + DBUG_PRINT("view_create_error", + ("Failed to create view '%s': %d: %s", query_str.str, + mysql_errno(mysql), mysql_error(mysql))); + + /* Log error to create view */ + verbose_msg("Failed to create view '%s' %d: %s", query_str.str, + mysql_errno(mysql), mysql_error(mysql)); + } + else + { + /* + Yes, it was possible to create this query as a view + */ + view_created= 1; + query= (char*)"SELECT * FROM mysqltest_tmp_v"; + query_len = strlen(query); + + /* + Collect warnings from create of the view that should otherwise + have been produced when the SELECT was executed + */ + append_warnings(&ds_warnings, cur_con->util_mysql); + } + + dynstr_free(&query_str); + + } + + if (sp_protocol_enabled && + complete_query && + match_re(&sp_re, query)) + { + /* + Create the query as a stored procedure + Drop first since sp can exist from a failed mysqltest run + */ + DYNAMIC_STRING query_str; + init_dynamic_string(&query_str, + "DROP PROCEDURE IF EXISTS mysqltest_tmp_sp;", + query_len+64, 256); + util_query(mysql, query_str.str); + dynstr_set(&query_str, "CREATE PROCEDURE mysqltest_tmp_sp()\n"); + dynstr_append_mem(&query_str, query, query_len); + if (util_query(mysql, query_str.str)) + { + /* + Failed to create the stored procedure for this query, + this is not fatal just run the query the normal way + */ + DBUG_PRINT("sp_create_error", + ("Failed to create sp '%s': %d: %s", query_str.str, + mysql_errno(mysql), mysql_error(mysql))); + + /* Log error to create sp */ + verbose_msg("Failed to create sp '%s' %d: %s", query_str.str, + mysql_errno(mysql), mysql_error(mysql)); + + } + else + { + sp_created= 1; + + query= (char*)"CALL mysqltest_tmp_sp()"; + query_len = strlen(query); + } + dynstr_free(&query_str); + } + + /* + Find out how to run this query + + Always run with normal C API if it's not a complete + SEND + REAP + + If it is a '?' in the query it may be a SQL level prepared + statement already and we can't do it twice + */ + if (ps_protocol_enabled && + complete_query && + match_re(&ps_re, query)) + run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings); + else + run_query_normal(mysql, command, flags, query, query_len, + ds, &ds_warnings); + + if (sp_created) + { + if (util_query(mysql, "DROP PROCEDURE mysqltest_tmp_sp ")) + die("Failed to drop sp: %d: %s", mysql_errno(mysql), mysql_error(mysql)); + } + + if (view_created) + { + if (util_query(mysql, "DROP VIEW mysqltest_tmp_v ")) + die("Failed to drop view: %d: %s", + mysql_errno(mysql), mysql_error(mysql)); + } + + if (command->record_file[0]) + { + + /* A result file was specified for _this_ query */ + if (record) + { + /* + Recording in progress + Dump the output from _this_ query to the specified record_file + */ + str_to_file(command->record_file, ds->str, ds->length); + + } else { + + /* + The output from _this_ query should be checked against an already + existing file which has been specified using --require or --result + */ + check_result(ds, command->record_file, command->require_file); + } + } + + dynstr_free(&ds_warnings); + if (ds == &ds_result) + dynstr_free(&ds_result); + if (command->type == Q_EVAL) + dynstr_free(&eval_query); +} + +/****************************************************************************/ +/* + Functions to detect different SQL statements +*/ + +char *re_eprint(int err) +{ + static char epbuf[100]; + size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL, + epbuf, sizeof(epbuf)); + assert(len <= sizeof(epbuf)); + return(epbuf); +} + +void init_re_comp(my_regex_t *re, const char* str) +{ + int err= my_regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB), + &my_charset_latin1); + if (err) + { + char erbuf[100]; + int len= my_regerror(err, re, erbuf, sizeof(erbuf)); + die("error %s, %d/%d `%s'\n", + re_eprint(err), len, (int)sizeof(erbuf), erbuf); + } +} + +void init_re(void) +{ + /* + Filter for queries that can be run using the + MySQL Prepared Statements C API + */ const char *ps_re_str = "^(" "[[:space:]]*REPLACE[[:space:]]|" @@ -3595,199 +5108,210 @@ static void ps_init_re(void) "[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|" "[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])"; - int err= my_regcomp(&ps_re, ps_re_str, - (REG_EXTENDED | REG_ICASE | REG_NOSUB), - &my_charset_latin1); - if (err) - { - char erbuf[100]; - int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf)); - fprintf(stderr, "error %s, %d/%d `%s'\n", - ps_eprint(err), len, (int)sizeof(erbuf), erbuf); - exit(1); - } + /* + Filter for queries that can be run using the + Stored procedures + */ + const char *sp_re_str =ps_re_str; + + /* + Filter for queries that can be run as views + */ + const char *view_re_str = + "^(" + "[[:space:]]*SELECT[[:space:]])"; + + init_re_comp(&ps_re, ps_re_str); + init_re_comp(&sp_re, sp_re_str); + init_re_comp(&view_re, view_re_str); } -static int ps_match_re(char *stmt_str) +int match_re(my_regex_t *re, char *str) { - int err= my_regexec(&ps_re, stmt_str, (size_t)0, NULL, 0); + int err= my_regexec(re, str, (size_t)0, NULL, 0); if (err == 0) return 1; else if (err == REG_NOMATCH) return 0; - else + { char erbuf[100]; - int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf)); - fprintf(stderr, "error %s, %d/%d `%s'\n", - ps_eprint(err), len, (int)sizeof(erbuf), erbuf); - exit(1); + int len= my_regerror(err, re, erbuf, sizeof(erbuf)); + die("error %s, %d/%d `%s'\n", + re_eprint(err), len, (int)sizeof(erbuf), erbuf); } + return 0; } -static char *ps_eprint(int err) -{ - static char epbuf[100]; - size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf)); - assert(len <= sizeof(epbuf)); - return(epbuf); -} - - -static void ps_free_reg(void) +void free_re(void) { my_regfree(&ps_re); + my_regfree(&sp_re); + my_regfree(&view_re); + my_regex_end(); } /****************************************************************************/ -void get_query_type(struct st_query* q) +void get_command_type(struct st_command* command) { char save; uint type; - DBUG_ENTER("get_query_type"); + DBUG_ENTER("get_command_type"); - if (*q->query == '}') + if (!parsing_disabled && *command->query == '}') { - q->type = Q_END_BLOCK; + command->type = Q_END_BLOCK; DBUG_VOID_RETURN; } - if (q->type != Q_COMMENT_WITH_COMMAND) - q->type = Q_QUERY; + if (command->type != Q_COMMENT_WITH_COMMAND) + command->type= parsing_disabled ? Q_COMMENT : Q_QUERY; - save=q->query[q->first_word_len]; - q->query[q->first_word_len]=0; - type=find_type(q->query, &command_typelib, 1+2); - q->query[q->first_word_len]=save; + save=command->query[command->first_word_len]; + command->query[command->first_word_len]=0; + type=find_type(command->query, &command_typelib, 1+2); + command->query[command->first_word_len]=save; if (type > 0) - q->type=(enum enum_commands) type; /* Found command */ - DBUG_VOID_RETURN; -} - - -static byte *get_var_key(const byte* var, uint* len, - my_bool __attribute__((unused)) t) -{ - register char* key; - key = ((VAR*)var)->name; - *len = ((VAR*)var)->name_len; - return (byte*)key; -} - -static VAR *var_init(VAR *v, const char *name, int name_len, const char *val, - int val_len) -{ - int val_alloc_len; - VAR *tmp_var; - if (!name_len && name) - name_len = strlen(name); - if (!val_len && val) - val_len = strlen(val) ; - val_alloc_len = val_len + 16; /* room to grow */ - if (!(tmp_var=v) && !(tmp_var = (VAR*)my_malloc(sizeof(*tmp_var) - + name_len, MYF(MY_WME)))) - die("Out of memory"); - - tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; - tmp_var->alloced = (v == 0); - - if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME)))) - die("Out of memory"); - - memcpy(tmp_var->name, name, name_len); - if (val) { - memcpy(tmp_var->str_val, val, val_len); - tmp_var->str_val[val_len]=0; + command->type=(enum enum_commands) type; /* Found command */ + /* + If queries are disabled, only recognize + --enable_parsing and --disable_parsing + */ + if (parsing_disabled && command->type != Q_ENABLE_PARSING && + command->type != Q_DISABLE_PARSING) + command->type= Q_COMMENT; + + /* + Look for case where "query" was explicitly specified to + force command being sent to server + */ + if (type == Q_QUERY) + { + /* Skip the "query" part */ + command->query= command->first_argument; + } + } + else if (command->type == Q_COMMENT_WITH_COMMAND && + command->first_word_len && + strcmp(command->query + command->first_word_len - 1, delimiter) == 0) + { + /* + Detect comment with command using extra delimiter + Ex --disable_query_log; + ^ Extra delimiter causing the command + to be skipped + */ + save= command->query[command->first_word_len-1]; + command->query[command->first_word_len-1]= 0; + type= find_type(command->query, &command_typelib, 1+2); + command->query[command->first_word_len-1]= save; + if (type > 0) + die("Extra delimiter \";\" found"); } - tmp_var->name_len = name_len; - tmp_var->str_val_len = val_len; - tmp_var->alloced_len = val_alloc_len; - tmp_var->int_val = (val) ? atoi(val) : 0; - tmp_var->int_dirty = 0; - return tmp_var; -} - -static void var_free(void *v) -{ - my_free(((VAR*) v)->str_val, MYF(MY_WME)); - if (((VAR*)v)->alloced) - my_free((char*) v, MYF(MY_WME)); -} - - -static VAR* var_from_env(const char *name, const char *def_val) -{ - const char *tmp; - VAR *v; - if (!(tmp = getenv(name))) - tmp = def_val; - - v = var_init(0, name, strlen(name), tmp, strlen(tmp)); - my_hash_insert(&var_hash, (byte*)v); - return v; -} - - -static void init_var_hash(MYSQL *mysql) -{ - VAR *v; - DBUG_ENTER("init_var_hash"); - if (hash_init(&var_hash, charset_info, - 1024, 0, 0, get_var_key, var_free, MYF(0))) - die("Variable hash initialization failed"); - if (opt_big_test) - my_hash_insert(&var_hash, (byte*) var_init(0,"BIG_TEST", 0, "1",0)); - v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0); - my_hash_insert(&var_hash, (byte*) v); - v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); - my_hash_insert(&var_hash, (byte*) v); - v= var_init(0,"DB", 2, db, 0); - my_hash_insert(&var_hash, (byte*) v); DBUG_VOID_RETURN; } + +/* + Record how many milliseconds it took to execute the test file + up until the current line and save it in the dynamic string ds_progress. + + The ds_progress will be dumped to .progress when + test run completes + +*/ + +void mark_progress(struct st_command* command __attribute__((unused)), + int line) +{ + char buf[32], *end; + ulonglong timer= timer_now(); + if (!progress_start) + progress_start= timer; + timer-= progress_start; + + /* Milliseconds since start */ + end= longlong2str(timer, buf, 10); + dynstr_append_mem(&ds_progress, buf, (int)(end-buf)); + dynstr_append_mem(&ds_progress, "\t", 1); + + /* Parser line number */ + end= int10_to_str(line, buf, 10); + dynstr_append_mem(&ds_progress, buf, (int)(end-buf)); + dynstr_append_mem(&ds_progress, "\t", 1); + + /* Filename */ + dynstr_append(&ds_progress, cur_file->file_name); + dynstr_append_mem(&ds_progress, ":", 1); + + /* Line in file */ + end= int10_to_str(cur_file->lineno, buf, 10); + dynstr_append_mem(&ds_progress, buf, (int)(end-buf)); + + + dynstr_append_mem(&ds_progress, "\n", 1); + +} + + int main(int argc, char **argv) { - int error = 0; - struct st_query *q; - my_bool require_file=0, q_send_flag=0, query_executed= 0, abort_flag= 0; + struct st_command *command; + my_bool require_file= 0, q_send_flag= 0; + uint command_executed= 0, last_command_executed= 0; char save_file[FN_REFLEN]; MY_STAT res_info; MY_INIT(argv[0]); - { - DBUG_ENTER("main"); - DBUG_PROCESS(argv[0]); - /* Use all time until exit if no explicit 'start_timer' */ - timer_start= timer_now(); + save_file[0]= 0; + TMPDIR[0]= 0; - save_file[0]=0; - TMPDIR[0]=0; - memset(cons, 0, sizeof(cons)); - cons_end = cons + MAX_CONS; - next_con = cons + 1; - cur_con = cons; + /* Init connections */ + memset(connections, 0, sizeof(connections)); + connections_end= connections + + (sizeof(connections)/sizeof(struct st_connection)) - 1; + next_con= connections + 1; + cur_con= connections; + /* Init file stack */ memset(file_stack, 0, sizeof(file_stack)); - memset(&master_pos, 0, sizeof(master_pos)); - file_stack_end= file_stack + MAX_INCLUDE_DEPTH - 1; + file_stack_end= + file_stack + (sizeof(file_stack)/sizeof(struct st_test_file)) - 1; cur_file= file_stack; - lineno = lineno_stack; - my_init_dynamic_array(&q_lines, sizeof(struct st_query*), INIT_Q_LINES, - INIT_Q_LINES); + /* Init block stack */ memset(block_stack, 0, sizeof(block_stack)); - block_stack_end= block_stack + BLOCK_STACK_DEPTH - 1; + block_stack_end= + block_stack + (sizeof(block_stack)/sizeof(struct st_block)) - 1; cur_block= block_stack; cur_block->ok= TRUE; /* Outer block should always be executed */ - cur_block->cmd= Q_UNKNOWN; + cur_block->cmd= cmd_none; - init_dynamic_string(&ds_res, "", 0, 65536); + my_init_dynamic_array(&q_lines, sizeof(struct st_command*), 1024, 1024); + + if (hash_init(&var_hash, charset_info, + 1024, 0, 0, get_var_key, var_free, MYF(0))) + die("Variable hash initialization failed"); + + memset(&master_pos, 0, sizeof(master_pos)); + + parser.current_line= parser.read_lines= 0; + memset(&var_reg, 0, sizeof(var_reg)); + +#ifdef __WIN__ + init_tmp_sh_file(); + init_win_path_patterns(); +#endif + + init_dynamic_string(&ds_res, "", 65536, 65536); + init_dynamic_string(&ds_progress, "", 0, 2048); parse_args(argc, argv); + + DBUG_PRINT("info",("result_file: '%s'", result_file ? result_file : "")); if (mysql_server_init(embedded_server_arg_count, embedded_server_args, (char**) embedded_server_groups)) @@ -3796,17 +5320,17 @@ int main(int argc, char **argv) { cur_file->file= stdin; cur_file->file_name= my_strdup("", MYF(MY_WME)); + cur_file->lineno= 1; } - *lineno=1; -#ifndef EMBEDDED_LIBRARY - if (manager_host) - init_manager(); -#endif - if (ps_protocol) - { + init_re(); + ps_protocol_enabled= ps_protocol; + sp_protocol_enabled= sp_protocol; + view_protocol_enabled= view_protocol; + cursor_protocol_enabled= cursor_protocol; + /* Cursor protcol implies ps protocol */ + if (cursor_protocol_enabled) ps_protocol_enabled= 1; - ps_init_re(); - } + if (!( mysql_init(&cur_con->mysql))) die("Failed in mysql_init()"); if (opt_compress) @@ -3815,18 +5339,30 @@ int main(int argc, char **argv) mysql_options(&cur_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name); #ifdef HAVE_OPENSSL + +#if MYSQL_VERSION_ID >= 50000 + opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */ +#endif + if (opt_use_ssl) + { mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); +#if MYSQL_VERSION_ID >= 50000 + mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, + &opt_ssl_verify_server_cert); +#endif + } #endif if (!(cur_con->name = my_strdup("default", MYF(MY_WME)))) die("Out of memory"); - if (safe_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock)) - die("Failed in mysql_real_connect(): %s", mysql_error(&cur_con->mysql)); + safe_connect(&cur_con->mysql, cur_con->name, host, user, pass, + db, port, unix_sock); - init_var_hash(&cur_con->mysql); + /* Use all time until exit if no explicit 'start_timer' */ + timer_start= timer_now(); /* Initialize $mysql_errno with -1, so we can @@ -3835,24 +5371,31 @@ int main(int argc, char **argv) */ var_set_errno(-1); - while (!abort_flag && !read_query(&q)) + if (opt_include) + { + open_file(opt_include); + } + + while (!read_command(&command)) { int current_line_inc = 1, processed = 0; - if (q->type == Q_UNKNOWN || q->type == Q_COMMENT_WITH_COMMAND) - get_query_type(q); + if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND) + get_command_type(command); if (cur_block->ok) { - q->last_argument= q->first_argument; + command->last_argument= command->first_argument; processed = 1; - switch (q->type) { - case Q_CONNECT: do_connect(q); break; - case Q_CONNECTION: select_connection(q); break; + switch (command->type) { + case Q_CONNECT: + do_connect(command); + break; + case Q_CONNECTION: select_connection(command); break; case Q_DISCONNECT: case Q_DIRTY_CLOSE: - close_connection(q); break; - case Q_RPL_PROBE: do_rpl_probe(q); break; - case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break; - case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break; + do_close_connection(command); break; + case Q_RPL_PROBE: do_rpl_probe(command); break; + case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(command); break; + case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(command); break; case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break; @@ -3861,27 +5404,27 @@ int main(int argc, char **argv) case Q_DISABLE_RESULT_LOG: disable_result_log=1; break; case Q_ENABLE_WARNINGS: disable_warnings=0; break; case Q_DISABLE_WARNINGS: disable_warnings=1; break; + case Q_ENABLE_PS_WARNINGS: disable_ps_warnings=0; break; + case Q_DISABLE_PS_WARNINGS: disable_ps_warnings=1; break; case Q_ENABLE_INFO: disable_info=0; break; case Q_DISABLE_INFO: disable_info=1; break; case Q_ENABLE_METADATA: display_metadata=1; break; case Q_DISABLE_METADATA: display_metadata=0; break; - case Q_SOURCE: do_source(q); break; - case Q_SLEEP: do_sleep(q, 0); break; - case Q_REAL_SLEEP: do_sleep(q, 1); break; - case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(q); break; - case Q_REQUIRE_MANAGER: do_require_manager(q); break; -#ifndef EMBEDDED_LIBRARY - case Q_SERVER_START: do_server_start(q); break; - case Q_SERVER_STOP: do_server_stop(q); break; -#endif - case Q_INC: do_modify_var(q, "inc", DO_INC); break; - case Q_DEC: do_modify_var(q, "dec", DO_DEC); break; - case Q_ECHO: do_echo(q); break; - case Q_SYSTEM: do_system(q); break; + case Q_SOURCE: do_source(command); break; + case Q_SLEEP: do_sleep(command, 0); break; + case Q_REAL_SLEEP: do_sleep(command, 1); break; + case Q_WAIT_FOR_SLAVE_TO_STOP: do_wait_for_slave_to_stop(command); break; + case Q_INC: do_modify_var(command, DO_INC); break; + case Q_DEC: do_modify_var(command, DO_DEC); break; + case Q_ECHO: do_echo(command); command_executed++; break; + case Q_SYSTEM: do_system(command); break; + case Q_REMOVE_FILE: do_remove_file(command); break; + case Q_FILE_EXIST: do_file_exist(command); break; + case Q_WRITE_FILE: do_write_file(command); break; + case Q_COPY_FILE: do_copy_file(command); break; + case Q_PERL: do_perl(command); break; case Q_DELIMITER: - strmake(delimiter, q->first_argument, sizeof(delimiter) - 1); - delimiter_length= strlen(delimiter); - q->last_argument= q->first_argument+delimiter_length; + do_delimiter(command); break; case Q_DISPLAY_VERTICAL_RESULTS: display_result_vertically= TRUE; @@ -3889,115 +5432,121 @@ int main(int argc, char **argv) case Q_DISPLAY_HORIZONTAL_RESULTS: display_result_vertically= FALSE; break; - case Q_LET: do_let(q); break; + case Q_LET: do_let(command); break; case Q_EVAL_RESULT: eval_result = 1; break; case Q_EVAL: - if (q->query == q->query_buf) + if (command->query == command->query_buf) { - q->query= q->first_argument; - q->first_word_len= 0; + command->query= command->first_argument; + command->first_word_len= 0; } /* fall through */ case Q_QUERY_VERTICAL: case Q_QUERY_HORIZONTAL: { my_bool old_display_result_vertically= display_result_vertically; - if (!q->query[q->first_word_len]) - { - /* This happens when we use 'query_..' on it's own line */ - q_send_flag=1; - DBUG_PRINT("info", - ("query: '%s' first_word_len: %d send_flag=1", - q->query, q->first_word_len)); - break; - } - /* fix up query pointer if this is * first iteration for this line */ - if (q->query == q->query_buf) - q->query += q->first_word_len + 1; - display_result_vertically= (q->type==Q_QUERY_VERTICAL); + + /* Remove "query_*" if this is first iteration */ + if (command->query == command->query_buf) + command->query= command->first_argument; + + display_result_vertically= (command->type == Q_QUERY_VERTICAL); if (save_file[0]) { - strmov(q->record_file,save_file); - q->require_file=require_file; + strmov(command->record_file,save_file); + command->require_file=require_file; save_file[0]=0; } - error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND); + run_query(&cur_con->mysql, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG); display_result_vertically= old_display_result_vertically; - q->last_argument= q->end; - query_executed= 1; + command->last_argument= command->end; + command_executed++; break; } case Q_QUERY: case Q_REAP: { - /* - We read the result always regardless of the mode for both full - query and read-result only (reap) - */ - int flags = QUERY_REAP; - if (q->type != Q_REAP) /* for a full query, enable the send stage */ - flags |= QUERY_SEND; - if (q_send_flag) - { - flags= QUERY_SEND; - q_send_flag=0; - } + int flags; + if (q_send_flag) + { + /* Last command was an empty 'send' */ + flags= QUERY_SEND_FLAG; + q_send_flag= 0; + } + else if (command->type == Q_REAP) + { + flags= QUERY_REAP_FLAG; + } + else + { + /* full query, both reap and send */ + flags= QUERY_REAP_FLAG | QUERY_SEND_FLAG; + } + if (save_file[0]) { - strmov(q->record_file,save_file); - q->require_file=require_file; + strmov(command->record_file,save_file); + command->require_file=require_file; save_file[0]=0; } - error |= run_query(&cur_con->mysql, q, flags); - query_executed= 1; - q->last_argument= q->end; + run_query(&cur_con->mysql, command, flags); + command_executed++; + command->last_argument= command->end; break; } case Q_SEND: - if (!q->query[q->first_word_len]) - { - /* This happens when we use 'send' on it's own line */ - q_send_flag=1; - break; - } - /* fix up query pointer if this is * first iteration for this line */ - if (q->query == q->query_buf) - q->query += q->first_word_len; + if (!*command->first_argument) + { + /* + This is a send without arguments, it indicates that _next_ query + should be send only + */ + q_send_flag= 1; + break; + } + + /* Remove "send" if this is first iteration */ + if (command->query == command->query_buf) + command->query= command->first_argument; + /* - run_query() can execute a query partially, depending on the flags - QUERY_SEND flag without QUERY_REAP tells it to just send the - query and read the result some time later when reap instruction + run_query() can execute a query partially, depending on the flags. + QUERY_SEND_FLAG flag without QUERY_REAP_FLAG tells it to just send + the query and read the result some time later when reap instruction is given on this connection. - */ - error |= run_query(&cur_con->mysql, q, QUERY_SEND); - query_executed= 1; - q->last_argument= q->end; + */ + run_query(&cur_con->mysql, command, QUERY_SEND_FLAG); + command_executed++; + command->last_argument= command->end; break; case Q_RESULT: - get_file_name(save_file,q); + do_get_file_name(save_file, command); require_file=0; break; case Q_ERROR: - global_expected_errors=get_errcodes(global_expected_errno,q); + do_get_errcodes(command); break; case Q_REQUIRE: - get_file_name(save_file,q); + do_get_file_name(save_file, command); require_file=1; break; case Q_REPLACE: - get_replace(q); + do_get_replace(command); break; + case Q_REPLACE_REGEX: + do_get_replace_regex(command); + break; case Q_REPLACE_COLUMN: - get_replace_column(q); + do_get_replace_column(command); break; case Q_SAVE_MASTER_POS: do_save_master_pos(); break; - case Q_SYNC_WITH_MASTER: do_sync_with_master(q); break; + case Q_SYNC_WITH_MASTER: do_sync_with_master(command); break; case Q_SYNC_SLAVE_WITH_MASTER: { do_save_master_pos(); - if (*q->first_argument) - select_connection(q); + if (*command->first_argument) + select_connection(command); else select_connection_name("slave"); do_sync_with_master2(0); @@ -4005,14 +5554,14 @@ int main(int argc, char **argv) } case Q_COMMENT: /* Ignore row */ case Q_COMMENT_WITH_COMMAND: - q->last_argument= q->end; + command->last_argument= command->end; break; case Q_PING: (void) mysql_ping(&cur_con->mysql); break; case Q_EXEC: - do_exec(q); - query_executed= 1; + do_exec(command); + command_executed++; break; case Q_START_TIMER: /* Overwrite possible earlier start of timer */ @@ -4021,10 +5570,9 @@ int main(int argc, char **argv) case Q_END_TIMER: /* End timer before ending mysqltest */ timer_output(); - got_end_timer= TRUE; break; case Q_CHARACTER_SET: - set_charset(q); + do_set_charset(command); break; case Q_DISABLE_PS_PROTOCOL: ps_protocol_enabled= 0; @@ -4033,48 +5581,117 @@ int main(int argc, char **argv) ps_protocol_enabled= ps_protocol; break; case Q_DISABLE_RECONNECT: - cur_con->mysql.reconnect= 0; + set_reconnect(&cur_con->mysql, 0); break; case Q_ENABLE_RECONNECT: - cur_con->mysql.reconnect= 1; + set_reconnect(&cur_con->mysql, 1); break; - case Q_EXIT: - abort_flag= 1; + case Q_DISABLE_PARSING: + if (parsing_disabled == 0) + parsing_disabled= 1; + else + die("Parsing is already disabled"); + break; + case Q_ENABLE_PARSING: + /* + Ensure we don't get parsing_disabled < 0 as this would accidentally + disable code we don't want to have disabled + */ + if (parsing_disabled == 1) + parsing_disabled= 0; + else + die("Parsing is already enabled"); break; - default: processed = 0; break; + case Q_DIE: + die("%s", command->first_argument); + break; + + default: + processed= 0; + break; } } if (!processed) { - current_line_inc = 0; - switch (q->type) { - case Q_WHILE: do_block(Q_WHILE, q); break; - case Q_IF: do_block(Q_IF, q); break; - case Q_END_BLOCK: do_done(q); break; + current_line_inc= 0; + switch (command->type) { + case Q_WHILE: do_block(cmd_while, command); break; + case Q_IF: do_block(cmd_if, command); break; + case Q_END_BLOCK: do_done(command); break; default: current_line_inc = 1; break; } } else - check_eol_junk(q->last_argument); + check_eol_junk(command->last_argument); - if (q->type != Q_ERROR) + if (command->type != Q_ERROR) { /* As soon as any non "error" command has been executed, the array with expected errors should be cleared */ - global_expected_errors= 0; - bzero((gptr) global_expected_errno, sizeof(global_expected_errno)); + memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); } + if (command_executed != last_command_executed) + { + /* + As soon as any command has been executed, + the replace structures should be cleared + */ + free_all_replace(); + } + last_command_executed= command_executed; + + + parser.current_line += current_line_inc; + if ( opt_mark_progress ) + mark_progress(command, parser.current_line); } start_lineno= 0; - if (!query_executed && result_file && my_stat(result_file, &res_info, 0)) + if (parsing_disabled) + die("Test ended with parsing disabled"); + + /* + The whole test has been executed _sucessfully_. + Time to compare result or save it to record file. + The entire output from test is now kept in ds_res. + */ + if (ds_res.length) + { + if (result_file) + { + if (record) + { + /* Dump the output from test to result file */ + str_to_file(result_file, ds_res.str, ds_res.length); + } + else + { + /* Check that the output from test is equal to result file + - detect missing result file + - detect zero size result file + */ + check_result(&ds_res, result_file, 0); + } + } + else + { + /* No result_file specified to compare with, print to stdout */ + printf("%s", ds_res.str); + } + } + else + { + die("The test didn't produce any output"); + } + + if (!command_executed && result_file && my_stat(result_file, &res_info, 0)) { /* my_stat() successful on result file. Check if we have not run a @@ -4083,114 +5700,49 @@ int main(int argc, char **argv) non-existing or non-readable file, we assume it's fine to have no query output from the test file, e.g. regarded as no error. */ - if (res_info.st_size) - error|= (RESULT_CONTENT_MISMATCH | RESULT_LENGTH_MISMATCH); - } - if (ds_res.length && !error) - { - if (result_file) - { - if (!record) - error |= check_result(&ds_res, result_file, q->require_file); - else - str_to_file(result_file, ds_res.str, ds_res.length); - } - else - { - /* Print the result to stdout */ - printf("%s", ds_res.str); - } + die("No queries executed but result file found!"); } + + if ( opt_mark_progress ) + dump_progress(result_file); + dynstr_free(&ds_progress); + dynstr_free(&ds_res); - if (!silent) - { - if (error) - printf("not ok\n"); - else - printf("ok\n"); - } - - if (!got_end_timer) - timer_output(); /* No end_timer cmd, end it */ + timer_output(); free_used_memory(); my_end(MY_CHECK_ERROR); - exit(error ? 1 : 0); - return error ? 1 : 0; /* Keep compiler happy */ - } + + /* Yes, if we got this far the test has suceeded! Sakila smiles */ + if (!silent) + printf("ok\n"); + exit(0); + return 0; /* Keep compiler happy */ } /* - Read arguments for embedded server and put them into - embedded_server_args_count and embedded_server_args[] + A primitive timer that give results in milliseconds if the + --timer-file= is given. The timer result is written + to that file when the result is available. To not confuse + mysql-test-run with an old obsolete result, we remove the file + before executing any commands. The time we measure is + + - If no explicit 'start_timer' or 'end_timer' is given in the + test case, the timer measure how long we execute in mysqltest. + + - If only 'start_timer' is given we measure how long we execute + from that point until we terminate mysqltest. + + - If only 'end_timer' is given we measure how long we execute + from that we enter mysqltest to the 'end_timer' is command is + executed. + + - If both 'start_timer' and 'end_timer' are given we measure + the time between executing the two commands. */ - -static int read_server_arguments(const char *name) -{ - char argument[1024],buff[FN_REFLEN], *str=0; - FILE *file; - - if (!test_if_hard_path(name)) - { - strxmov(buff, opt_basedir, name, NullS); - name=buff; - } - fn_format(buff,name,"","",4); - - if (!embedded_server_arg_count) - { - embedded_server_arg_count=1; - embedded_server_args[0]= (char*) ""; /* Progname */ - } - if (!(file=my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) - return 1; - while (embedded_server_arg_count < MAX_SERVER_ARGS && - (str=fgets(argument,sizeof(argument), file))) - { - *(strend(str)-1)=0; /* Remove end newline */ - if (!(embedded_server_args[embedded_server_arg_count]= - (char*) my_strdup(str,MYF(MY_WME)))) - { - my_fclose(file,MYF(0)); - return 1; - } - embedded_server_arg_count++; - } - my_fclose(file,MYF(0)); - if (str) - { - fprintf(stderr,"Too many arguments in option file: %s\n",name); - return 1; - } - return 0; -} - -/****************************************************************************\ - * - * A primitive timer that give results in milliseconds if the - * --timer-file= is given. The timer result is written - * to that file when the result is available. To not confuse - * mysql-test-run with an old obsolete result, we remove the file - * before executing any commands. The time we measure is - * - * - If no explicit 'start_timer' or 'end_timer' is given in the - * test case, the timer measure how long we execute in mysqltest. - * - * - If only 'start_timer' is given we measure how long we execute - * from that point until we terminate mysqltest. - * - * - If only 'end_timer' is given we measure how long we execute - * from that we enter mysqltest to the 'end_timer' is command is - * executed. - * - * - If both 'start_timer' and 'end_timer' are given we measure - * the time between executing the two commands. - * -\****************************************************************************/ - -static void timer_output(void) +void timer_output(void) { if (timer_file) { @@ -4198,25 +5750,160 @@ static void timer_output(void) ulonglong timer= timer_now() - timer_start; end= longlong2str(timer, buf, 10); str_to_file(timer_file,buf, (int) (end-buf)); + /* Timer has been written to the file, don't use it anymore */ + timer_file= 0; } } -static ulonglong timer_now(void) + +ulonglong timer_now(void) { return my_getsystime() / 10000; } -/**************************************************************************** -* Handle replacement of strings -****************************************************************************/ -#define PC_MALLOC 256 /* Bytes for pointers */ -#define PS_MALLOC 512 /* Bytes for data */ +/* + Get arguments for replace_columns. The syntax is: + replace-column column_number to_string [column_number to_string ...] + Where each argument may be quoted with ' or " + A argument may also be a variable, in which case the value of the + variable is replaced. +*/ + +void do_get_replace_column(struct st_command *command) +{ + char *from= command->first_argument; + char *buff, *start; + DBUG_ENTER("get_replace_columns"); + + free_replace_column(); + if (!*from) + die("Missing argument in %s", command->query); + + /* Allocate a buffer for results */ + start= buff= my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); + while (*from) + { + char *to; + uint column_number; + + to= get_string(&buff, &from, command); + if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS) + die("Wrong column number to replace_column in '%s'", command->query); + if (!*from) + die("Wrong number of arguments to replace_column in '%s'", command->query); + to= get_string(&buff, &from, command); + my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR); + replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE)); + set_if_bigger(max_replace_column, column_number); + } + my_free(start, MYF(0)); + command->last_argument= command->end; +} + + +void free_replace_column() +{ + uint i; + for (i=0 ; i < max_replace_column ; i++) + { + if (replace_column[i]) + { + my_free(replace_column[i], 0); + replace_column[i]= 0; + } + } + max_replace_column= 0; +} + + +/****************************************************************************/ +/* + Replace functions +*/ + +/* Definitions for replace result */ + +typedef struct st_pointer_array { /* when using array-strings */ + TYPELIB typelib; /* Pointer to strings */ + byte *str; /* Strings is here */ + int7 *flag; /* Flag about each var. */ + uint array_allocs,max_count,length,max_length; +} POINTER_ARRAY; + +struct st_replace; +struct st_replace *init_replace(my_string *from, my_string *to, uint count, + my_string word_end_chars); +int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name); +void replace_strings_append(struct st_replace *rep, DYNAMIC_STRING* ds, + const char *from, int len); +void free_pointer_array(POINTER_ARRAY *pa); + +struct st_replace *glob_replace; + +/* + Get arguments for replace. The syntax is: + replace from to [from to ...] + Where each argument may be quoted with ' or " + A argument may also be a variable, in which case the value of the + variable is replaced. +*/ + +void do_get_replace(struct st_command *command) +{ + uint i; + char *from= command->first_argument; + char *buff, *start; + char word_end_chars[256], *pos; + POINTER_ARRAY to_array, from_array; + DBUG_ENTER("get_replace"); + + free_replace(); + + bzero((char*) &to_array,sizeof(to_array)); + bzero((char*) &from_array,sizeof(from_array)); + if (!*from) + die("Missing argument in %s", command->query); + start= buff= my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); + while (*from) + { + char *to= buff; + to= get_string(&buff, &from, command); + if (!*from) + die("Wrong number of arguments to replace_result in '%s'", + command->query); + insert_pointer_name(&from_array,to); + to= get_string(&buff, &from, command); + insert_pointer_name(&to_array,to); + } + for (i= 1,pos= word_end_chars ; i < 256 ; i++) + if (my_isspace(charset_info,i)) + *pos++= i; + *pos=0; /* End pointer */ + if (!(glob_replace= init_replace((char**) from_array.typelib.type_names, + (char**) to_array.typelib.type_names, + (uint) from_array.typelib.count, + word_end_chars))) + die("Can't initialize replace from '%s'", command->query); + free_pointer_array(&from_array); + free_pointer_array(&to_array); + my_free(start, MYF(0)); + command->last_argument= command->end; + DBUG_VOID_RETURN; +} + + +void free_replace() +{ + DBUG_ENTER("free_replace"); + if (glob_replace) + { + my_free((char*) glob_replace,MYF(0)); + glob_replace=0; + } + DBUG_VOID_RETURN; +} -#define SPACE_CHAR 256 -#define START_OF_LINE 257 -#define END_OF_LINE 258 -#define LAST_CHAR_CODE 259 typedef struct st_replace { bool found; @@ -4230,99 +5917,514 @@ typedef struct st_replace_found { int from_offset; } REPLACE_STRING; + +void replace_strings_append(REPLACE *rep, DYNAMIC_STRING* ds, + const char *str, int len) +{ + reg1 REPLACE *rep_pos; + reg2 REPLACE_STRING *rep_str; + const char *start, *from; + DBUG_ENTER("replace_strings_append"); + + start= from= str; + rep_pos=rep+1; + for (;;) + { + /* Loop through states */ + DBUG_PRINT("info", ("Looping through states")); + while (!rep_pos->found) + rep_pos= rep_pos->next[(uchar) *from++]; + + /* Does this state contain a string to be replaced */ + if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string) + { + /* No match found */ + dynstr_append_mem(ds, start, from - start - 1); + DBUG_PRINT("exit", ("Found no more string to replace, appended: %s", start)); + DBUG_VOID_RETURN; + } + + /* Found a string that needs to be replaced */ + DBUG_PRINT("info", ("found: %d, to_offset: %d, from_offset: %d, string: %s", + rep_str->found, rep_str->to_offset, + rep_str->from_offset, rep_str->replace_string)); + + /* Append part of original string before replace string */ + dynstr_append_mem(ds, start, (from - rep_str->to_offset) - start); + + /* Append replace string */ + dynstr_append_mem(ds, rep_str->replace_string, + strlen(rep_str->replace_string)); + + if (!*(from-=rep_str->from_offset) && rep_pos->found != 2) + { + /* End of from string */ + DBUG_PRINT("exit", ("Found end of from string")); + DBUG_VOID_RETURN; + } + DBUG_ASSERT(from <= str+len); + start= from; + rep_pos=rep; + } +} + + +/* + Regex replace functions +*/ + + +/* Stores regex substitutions */ + +struct st_regex +{ + char* pattern; /* Pattern to be replaced */ + char* replace; /* String or expression to replace the pattern with */ + int icase; /* true if the match is case insensitive */ +}; + +struct st_replace_regex +{ + DYNAMIC_ARRAY regex_arr; /* stores a list of st_regex subsitutions */ + + /* + Temporary storage areas for substitutions. To reduce unnessary copying + and memory freeing/allocation, we pre-allocate two buffers, and alternate + their use, one for input/one for output, the roles changing on the next + st_regex substition. At the end of substitutions buf points to the + one containing the final result. + */ + char* buf; + char* even_buf; + char* odd_buf; + int even_buf_len; + int odd_buf_len; +}; + +struct st_replace_regex *glob_replace_regex= 0; + +int reg_replace(char** buf_p, int* buf_len_p, char *pattern, char *replace, + char *string, int icase); + + + +/* + Finds the next (non-escaped) '/' in the expression. + (If the character '/' is needed, it can be escaped using '\'.) +*/ + +#define PARSE_REGEX_ARG \ + while (p < expr_end) \ + { \ + char c= *p; \ + if (c == '/') \ + { \ + if (last_c == '\\') \ + { \ + buf_p[-1]= '/'; \ + } \ + else \ + { \ + *buf_p++ = 0; \ + break; \ + } \ + } \ + else \ + *buf_p++ = c; \ + \ + last_c= c; \ + p++; \ + } \ + \ +/* + Initializes the regular substitution expression to be used in the + result output of test. + + Returns: st_replace_regex struct with pairs of substitutions +*/ + +struct st_replace_regex* init_replace_regex(char* expr) +{ + struct st_replace_regex* res; + char* buf,*expr_end; + char* p; + char* buf_p; + uint expr_len= strlen(expr); + char last_c = 0; + struct st_regex reg; + + /* my_malloc() will die on fail with MY_FAE */ + res=(struct st_replace_regex*)my_malloc( + sizeof(*res)+expr_len ,MYF(MY_FAE+MY_WME)); + my_init_dynamic_array(&res->regex_arr,sizeof(struct st_regex),128,128); + + buf= (char*)res + sizeof(*res); + expr_end= expr + expr_len; + p= expr; + buf_p= buf; + + /* for each regexp substitution statement */ + while (p < expr_end) + { + bzero(®,sizeof(reg)); + /* find the start of the statement */ + while (p < expr_end) + { + if (*p == '/') + break; + p++; + } + + if (p == expr_end || ++p == expr_end) + { + if (res->regex_arr.elements) + break; + else + goto err; + } + /* we found the start */ + reg.pattern= buf_p; + + /* Find first argument -- pattern string to be removed */ + PARSE_REGEX_ARG + + if (p == expr_end || ++p == expr_end) + goto err; + + /* buf_p now points to the replacement pattern terminated with \0 */ + reg.replace= buf_p; + + /* Find second argument -- replace string to replace pattern */ + PARSE_REGEX_ARG + + if (p == expr_end) + goto err; + + /* skip the ending '/' in the statement */ + p++; + + /* Check if we should do matching case insensitive */ + if (p < expr_end && *p == 'i') + reg.icase= 1; + + /* done parsing the statement, now place it in regex_arr */ + if (insert_dynamic(&res->regex_arr,(gptr) ®)) + die("Out of memory"); + } + res->odd_buf_len= res->even_buf_len= 8192; + res->even_buf= (char*)my_malloc(res->even_buf_len,MYF(MY_WME+MY_FAE)); + res->odd_buf= (char*)my_malloc(res->odd_buf_len,MYF(MY_WME+MY_FAE)); + res->buf= res->even_buf; + + return res; + +err: + my_free((gptr)res,0); + die("Error parsing replace_regex \"%s\"", expr); + return 0; +} + +/* + Execute all substitutions on val. + + Returns: true if substituition was made, false otherwise + Side-effect: Sets r->buf to be the buffer with all substitutions done. + + IN: + struct st_replace_regex* r + char* val + Out: + struct st_replace_regex* r + r->buf points at the resulting buffer + r->even_buf and r->odd_buf might have been reallocated + r->even_buf_len and r->odd_buf_len might have been changed + + TODO: at some point figure out if there is a way to do everything + in one pass +*/ + +int multi_reg_replace(struct st_replace_regex* r,char* val) +{ + uint i; + char* in_buf, *out_buf; + int* buf_len_p; + + in_buf= val; + out_buf= r->even_buf; + buf_len_p= &r->even_buf_len; + r->buf= 0; + + /* For each substitution, do the replace */ + for (i= 0; i < r->regex_arr.elements; i++) + { + struct st_regex re; + char* save_out_buf= out_buf; + + get_dynamic(&r->regex_arr,(gptr)&re,i); + + if (!reg_replace(&out_buf, buf_len_p, re.pattern, re.replace, + in_buf, re.icase)) + { + /* if the buffer has been reallocated, make adjustements */ + if (save_out_buf != out_buf) + { + if (save_out_buf == r->even_buf) + r->even_buf= out_buf; + else + r->odd_buf= out_buf; + } + + r->buf= out_buf; + if (in_buf == val) + in_buf= r->odd_buf; + + swap_variables(char*,in_buf,out_buf); + + buf_len_p= (out_buf == r->even_buf) ? &r->even_buf_len : + &r->odd_buf_len; + } + } + + return (r->buf == 0); +} + +/* + Parse the regular expression to be used in all result files + from now on. + + The syntax is --replace_regex /from/to/i /from/to/i ... + i means case-insensitive match. If omitted, the match is + case-sensitive + +*/ +void do_get_replace_regex(struct st_command *command) +{ + char *expr= command->first_argument; + free_replace_regex(); + if (!(glob_replace_regex=init_replace_regex(expr))) + die("Could not init replace_regex"); + command->last_argument= command->end; +} + +void free_replace_regex() +{ + if (glob_replace_regex) + { + delete_dynamic(&glob_replace_regex->regex_arr); + my_free(glob_replace_regex->even_buf,MYF(MY_ALLOW_ZERO_PTR)); + my_free(glob_replace_regex->odd_buf,MYF(MY_ALLOW_ZERO_PTR)); + my_free((char*) glob_replace_regex,MYF(0)); + glob_replace_regex=0; + } +} + + + +/* + auxiluary macro used by reg_replace + makes sure the result buffer has sufficient length +*/ +#define SECURE_REG_BUF if (buf_len < need_buf_len) \ + { \ + int off= res_p - buf; \ + buf= (char*)my_realloc(buf,need_buf_len,MYF(MY_WME+MY_FAE)); \ + res_p= buf + off; \ + buf_len= need_buf_len; \ + } \ + \ +/* + Performs a regex substitution + + IN: + + buf_p - result buffer pointer. Will change if reallocated + buf_len_p - result buffer length. Will change if the buffer is reallocated + pattern - regexp pattern to match + replace - replacement expression + string - the string to perform substituions in + icase - flag, if set to 1 the match is case insensitive +*/ +int reg_replace(char** buf_p, int* buf_len_p, char *pattern, + char *replace, char *string, int icase) +{ + my_regex_t r; + my_regmatch_t *subs; + char *buf_end, *replace_end; + char *buf= *buf_p; + int len; + int buf_len, need_buf_len; + int cflags= REG_EXTENDED; + int err_code; + char *res_p,*str_p,*str_end; + + buf_len= *buf_len_p; + len= strlen(string); + str_end= string + len; + + /* start with a buffer of a reasonable size that hopefully will not + need to be reallocated + */ + need_buf_len= len * 2 + 1; + res_p= buf; + + SECURE_REG_BUF + + buf_end= buf + buf_len; + + if (icase) + cflags|= REG_ICASE; + + if ((err_code= my_regcomp(&r,pattern,cflags,&my_charset_latin1))) + { + check_regerr(&r,err_code); + return 1; + } + + subs= (my_regmatch_t*)my_malloc(sizeof(my_regmatch_t) * (r.re_nsub+1), + MYF(MY_WME+MY_FAE)); + + *res_p= 0; + str_p= string; + replace_end= replace + strlen(replace); + + /* for each pattern match instance perform a replacement */ + while (!err_code) + { + /* find the match */ + err_code= my_regexec(&r,str_p, r.re_nsub+1, subs, + (str_p == string) ? REG_NOTBOL : 0); + + /* if regular expression error (eg. bad syntax, or out of memory) */ + if (err_code && err_code != REG_NOMATCH) + { + check_regerr(&r,err_code); + my_regfree(&r); + return 1; + } + + /* if match found */ + if (!err_code) + { + char* expr_p= replace; + int c; + + /* + we need at least what we have so far in the buffer + the part + before this match + */ + need_buf_len= (res_p - buf) + subs[0].rm_so; + + /* on this pass, calculate the memory for the result buffer */ + while (expr_p < replace_end) + { + int back_ref_num= -1; + c= *expr_p; + + if (c == '\\' && expr_p + 1 < replace_end) + { + back_ref_num= expr_p[1] - '0'; + } + + /* found a valid back_ref (eg. \1)*/ + if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub) + { + int start_off,end_off; + if ((start_off=subs[back_ref_num].rm_so) > -1 && + (end_off=subs[back_ref_num].rm_eo) > -1) + { + need_buf_len += (end_off - start_off); + } + expr_p += 2; + } + else + { + expr_p++; + need_buf_len++; + } + } + need_buf_len++; + /* + now that we know the size of the buffer, + make sure it is big enough + */ + SECURE_REG_BUF + + /* copy the pre-match part */ + if (subs[0].rm_so) + { + memcpy(res_p, str_p, subs[0].rm_so); + res_p+= subs[0].rm_so; + } + + expr_p= replace; + + /* copy the match and expand back_refs */ + while (expr_p < replace_end) + { + int back_ref_num= -1; + c= *expr_p; + + if (c == '\\' && expr_p + 1 < replace_end) + { + back_ref_num= expr_p[1] - '0'; + } + + if (back_ref_num >= 0 && back_ref_num <= (int)r.re_nsub) + { + int start_off,end_off; + if ((start_off=subs[back_ref_num].rm_so) > -1 && + (end_off=subs[back_ref_num].rm_eo) > -1) + { + int block_len= end_off - start_off; + memcpy(res_p,str_p + start_off, block_len); + res_p += block_len; + } + expr_p += 2; + } + else + { + *res_p++ = *expr_p++; + } + } + + /* handle the post-match part */ + if (subs[0].rm_so == subs[0].rm_eo) + { + if (str_p + subs[0].rm_so >= str_end) + break; + str_p += subs[0].rm_eo ; + *res_p++ = *str_p++; + } + else + { + str_p += subs[0].rm_eo; + } + } + else /* no match this time, just copy the string as is */ + { + int left_in_str= str_end-str_p; + need_buf_len= (res_p-buf) + left_in_str; + SECURE_REG_BUF + memcpy(res_p,str_p,left_in_str); + res_p += left_in_str; + str_p= str_end; + } + } + my_free((gptr)subs, MYF(0)); + my_regfree(&r); + *res_p= 0; + *buf_p= buf; + *buf_len_p= buf_len; + return 0; +} + + #ifndef WORD_BIT #define WORD_BIT (8*sizeof(uint)) #endif - -static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name) -{ - uint i,length,old_count; - byte *new_pos; - const char **new_array; - DBUG_ENTER("insert_pointer_name"); - - if (! pa->typelib.count) - { - if (!(pa->typelib.type_names=(const char **) - my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/ - (sizeof(my_string)+sizeof(*pa->flag))* - (sizeof(my_string)+sizeof(*pa->flag))),MYF(MY_WME)))) - DBUG_RETURN(-1); - if (!(pa->str= (byte*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD), - MYF(MY_WME)))) - { - my_free((gptr) pa->typelib.type_names,MYF(0)); - DBUG_RETURN (-1); - } - pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(byte*)+ - sizeof(*pa->flag)); - pa->flag= (int7*) (pa->typelib.type_names+pa->max_count); - pa->length=0; - pa->max_length=PS_MALLOC-MALLOC_OVERHEAD; - pa->array_allocs=1; - } - length=(uint) strlen(name)+1; - if (pa->length+length >= pa->max_length) - { - if (!(new_pos= (byte*) my_realloc((gptr) pa->str, - (uint) (pa->max_length+PS_MALLOC), - MYF(MY_WME)))) - DBUG_RETURN(1); - if (new_pos != pa->str) - { - my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str); - for (i=0 ; i < pa->typelib.count ; i++) - pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff, - char*); - pa->str=new_pos; - } - pa->max_length+=PS_MALLOC; - } - if (pa->typelib.count >= pa->max_count-1) - { - int len; - pa->array_allocs++; - len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD); - if (!(new_array=(const char **) my_realloc((gptr) pa->typelib.type_names, - (uint) len/ - (sizeof(byte*)+sizeof(*pa->flag))* - (sizeof(byte*)+sizeof(*pa->flag)), - MYF(MY_WME)))) - DBUG_RETURN(1); - pa->typelib.type_names=new_array; - old_count=pa->max_count; - pa->max_count=len/(sizeof(byte*) + sizeof(*pa->flag)); - pa->flag= (int7*) (pa->typelib.type_names+pa->max_count); - memcpy((byte*) pa->flag,(my_string) (pa->typelib.type_names+old_count), - old_count*sizeof(*pa->flag)); - } - pa->flag[pa->typelib.count]=0; /* Reset flag */ - pa->typelib.type_names[pa->typelib.count++]= pa->str+pa->length; - pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */ - VOID(strmov(pa->str+pa->length,name)); - pa->length+=length; - DBUG_RETURN(0); -} /* insert_pointer_name */ - - - /* free pointer array */ - -void free_pointer_array(POINTER_ARRAY *pa) -{ - if (pa->typelib.count) - { - pa->typelib.count=0; - my_free((gptr) pa->typelib.type_names,MYF(0)); - pa->typelib.type_names=0; - my_free((gptr) pa->str,MYF(0)); - } -} /* free_pointer_array */ - - - /* Code for replace rutines */ - #define SET_MALLOC_HUNC 64 +#define LAST_CHAR_CODE 259 typedef struct st_rep_set { uint *bits; /* Pointer to used sets */ @@ -4354,32 +6456,48 @@ typedef struct st_follow { } FOLLOWS; -static int init_sets(REP_SETS *sets,uint states); -static REP_SET *make_new_set(REP_SETS *sets); -static void make_sets_invisible(REP_SETS *sets); -static void free_last_set(REP_SETS *sets); -static void free_sets(REP_SETS *sets); -static void internal_set_bit(REP_SET *set, uint bit); -static void internal_clear_bit(REP_SET *set, uint bit); -static void or_bits(REP_SET *to,REP_SET *from); -static void copy_bits(REP_SET *to,REP_SET *from); -static int cmp_bits(REP_SET *set1,REP_SET *set2); -static int get_next_bit(REP_SET *set,uint lastpos); -static int find_set(REP_SETS *sets,REP_SET *find); -static int find_found(FOUND_SET *found_set,uint table_offset, - int found_offset); -static uint start_at_word(my_string pos); -static uint end_of_word(my_string pos); -static uint replace_len(my_string pos); +int init_sets(REP_SETS *sets,uint states); +REP_SET *make_new_set(REP_SETS *sets); +void make_sets_invisible(REP_SETS *sets); +void free_last_set(REP_SETS *sets); +void free_sets(REP_SETS *sets); +void internal_set_bit(REP_SET *set, uint bit); +void internal_clear_bit(REP_SET *set, uint bit); +void or_bits(REP_SET *to,REP_SET *from); +void copy_bits(REP_SET *to,REP_SET *from); +int cmp_bits(REP_SET *set1,REP_SET *set2); +int get_next_bit(REP_SET *set,uint lastpos); +int find_set(REP_SETS *sets,REP_SET *find); +int find_found(FOUND_SET *found_set,uint table_offset, + int found_offset); +uint start_at_word(my_string pos); +uint end_of_word(my_string pos); static uint found_sets=0; - /* Init a replace structure for further calls */ +uint replace_len(my_string str) +{ + uint len=0; + while (*str) + { + if (str[0] == '\\' && str[1]) + str++; + str++; + len++; + } + return len; +} + +/* Init a replace structure for further calls */ REPLACE *init_replace(my_string *from, my_string *to,uint count, my_string word_end_chars) { + static const int SPACE_CHAR= 256; + static const int START_OF_LINE= 257; + static const int END_OF_LINE= 258; + uint i,j,states,set_nr,len,result_len,max_length,found_end,bits_set,bit_nr; int used_sets,chr,default_state; char used_chars[LAST_CHAR_CODE],is_word_end[256]; @@ -4432,7 +6550,7 @@ REPLACE *init_replace(my_string *from, my_string *to,uint count, DBUG_RETURN(0); } - /* Init follow_ptr[] */ + /* Init follow_ptr[] */ for (i=0, states=1, follow_ptr=follow+1 ; i < count ; i++) { if (from[i][0] == '\\' && from[i][1] == '^') @@ -4615,7 +6733,7 @@ REPLACE *init_replace(my_string *from, my_string *to,uint count, } } - /* Alloc replace structure for the replace-state-machine */ + /* Alloc replace structure for the replace-state-machine */ if ((replace=(REPLACE*) my_malloc(sizeof(REPLACE)*(sets.count)+ sizeof(REPLACE_STRING)*(found_sets+1)+ @@ -4658,7 +6776,7 @@ REPLACE *init_replace(my_string *from, my_string *to,uint count, } -static int init_sets(REP_SETS *sets,uint states) +int init_sets(REP_SETS *sets,uint states) { bzero((char*) sets,sizeof(*sets)); sets->size_of_bits=((states+7)/8); @@ -4674,16 +6792,16 @@ static int init_sets(REP_SETS *sets,uint states) return 0; } - /* Make help sets invisible for nicer codeing */ +/* Make help sets invisible for nicer codeing */ -static void make_sets_invisible(REP_SETS *sets) +void make_sets_invisible(REP_SETS *sets) { sets->invisible=sets->count; sets->set+=sets->count; sets->count=0; } -static REP_SET *make_new_set(REP_SETS *sets) +REP_SET *make_new_set(REP_SETS *sets) { uint i,count,*bit_buffer; REP_SET *set; @@ -4701,7 +6819,7 @@ static REP_SET *make_new_set(REP_SETS *sets) } count=sets->count+sets->invisible+SET_MALLOC_HUNC; if (!(set=(REP_SET*) my_realloc((gptr) sets->set_buffer, - sizeof(REP_SET)*count, + sizeof(REP_SET)*count, MYF(MY_WME)))) return 0; sets->set_buffer=set; @@ -4720,34 +6838,34 @@ static REP_SET *make_new_set(REP_SETS *sets) return make_new_set(sets); } -static void free_last_set(REP_SETS *sets) +void free_last_set(REP_SETS *sets) { sets->count--; sets->extra++; return; } -static void free_sets(REP_SETS *sets) +void free_sets(REP_SETS *sets) { my_free((gptr)sets->set_buffer,MYF(0)); my_free((gptr)sets->bit_buffer,MYF(0)); return; } -static void internal_set_bit(REP_SET *set, uint bit) +void internal_set_bit(REP_SET *set, uint bit) { set->bits[bit / WORD_BIT] |= 1 << (bit % WORD_BIT); return; } -static void internal_clear_bit(REP_SET *set, uint bit) +void internal_clear_bit(REP_SET *set, uint bit) { set->bits[bit / WORD_BIT] &= ~ (1 << (bit % WORD_BIT)); return; } -static void or_bits(REP_SET *to,REP_SET *from) +void or_bits(REP_SET *to,REP_SET *from) { reg1 uint i; for (i=0 ; i < to->size_of_bits ; i++) @@ -4755,22 +6873,22 @@ static void or_bits(REP_SET *to,REP_SET *from) return; } -static void copy_bits(REP_SET *to,REP_SET *from) +void copy_bits(REP_SET *to,REP_SET *from) { memcpy((byte*) to->bits,(byte*) from->bits, (size_t) (sizeof(uint) * to->size_of_bits)); } -static int cmp_bits(REP_SET *set1,REP_SET *set2) +int cmp_bits(REP_SET *set1,REP_SET *set2) { return bcmp((byte*) set1->bits,(byte*) set2->bits, sizeof(uint) * set1->size_of_bits); } - /* Get next set bit from set. */ +/* Get next set bit from set. */ -static int get_next_bit(REP_SET *set,uint lastpos) +int get_next_bit(REP_SET *set,uint lastpos) { uint pos,*start,*end,bits; @@ -4791,11 +6909,11 @@ static int get_next_bit(REP_SET *set,uint lastpos) return pos; } - /* find if there is a same set in sets. If there is, use it and - free given set, else put in given set in sets and return it's - position */ +/* find if there is a same set in sets. If there is, use it and + free given set, else put in given set in sets and return its + position */ -static int find_set(REP_SETS *sets,REP_SET *find) +int find_set(REP_SETS *sets,REP_SET *find) { uint i; for (i=0 ; i < sets->count-1 ; i++) @@ -4809,14 +6927,14 @@ static int find_set(REP_SETS *sets,REP_SET *find) return i; /* return new postion */ } - /* find if there is a found_set with same table_offset & found_offset - If there is return offset to it, else add new offset and return pos. - Pos returned is -offset-2 in found_set_structure because it's is - saved in set->next and set->next[] >= 0 points to next set and - set->next[] == -1 is reserved for end without replaces. - */ +/* find if there is a found_set with same table_offset & found_offset + If there is return offset to it, else add new offset and return pos. + Pos returned is -offset-2 in found_set_structure because it is + saved in set->next and set->next[] >= 0 points to next set and + set->next[] == -1 is reserved for end without replaces. +*/ -static int find_found(FOUND_SET *found_set,uint table_offset, int found_offset) +int find_found(FOUND_SET *found_set,uint table_offset, int found_offset) { int i; for (i=0 ; (uint) i < found_sets ; i++) @@ -4829,251 +6947,155 @@ static int find_found(FOUND_SET *found_set,uint table_offset, int found_offset) return -i-2; /* return new postion */ } - /* Return 1 if regexp starts with \b or ends with \b*/ +/* Return 1 if regexp starts with \b or ends with \b*/ -static uint start_at_word(my_string pos) +uint start_at_word(my_string pos) { return (((!bcmp(pos,"\\b",2) && pos[2]) || !bcmp(pos,"\\^",2)) ? 1 : 0); } -static uint end_of_word(my_string pos) +uint end_of_word(my_string pos) { my_string end=strend(pos); return ((end > pos+2 && !bcmp(end-2,"\\b",2)) || (end >= pos+2 && !bcmp(end-2,"\\$",2))) ? - 1 : 0; + 1 : 0; } - -static uint replace_len(my_string str) -{ - uint len=0; - while (*str) - { - if (str[0] == '\\' && str[1]) - str++; - str++; - len++; - } - return len; -} - - - /* Replace strings; Return length of result string */ - -uint replace_strings(REPLACE *rep, my_string *start,uint *max_length, - const char *from) -{ - reg1 REPLACE *rep_pos; - reg2 REPLACE_STRING *rep_str; - my_string to,end,pos,new_str; - - end=(to= *start) + *max_length-1; - rep_pos=rep+1; - for (;;) - { - while (!rep_pos->found) - { - rep_pos= rep_pos->next[(uchar) *from]; - if (to == end) - { - (*max_length)+=8192; - if (!(new_str=my_realloc(*start,*max_length,MYF(MY_WME)))) - return (uint) -1; - to=new_str+(to - *start); - end=(*start=new_str)+ *max_length-1; - } - *to++= *from++; - } - if (!(rep_str = ((REPLACE_STRING*) rep_pos))->replace_string) - return (uint) (to - *start)-1; - to-=rep_str->to_offset; - for (pos=rep_str->replace_string; *pos ; pos++) - { - if (to == end) - { - (*max_length)*=2; - if (!(new_str=my_realloc(*start,*max_length,MYF(MY_WME)))) - return (uint) -1; - to=new_str+(to - *start); - end=(*start=new_str)+ *max_length-1; - } - *to++= *pos; - } - if (!*(from-=rep_str->from_offset) && rep_pos->found != 2) - return (uint) (to - *start); - rep_pos=rep; - } -} - -static int initialize_replace_buffer(void) -{ - out_length=8192; - if (!(out_buff=my_malloc(out_length,MYF(MY_WME)))) - return(1); - return 0; -} - -static void free_replace_buffer(void) -{ - my_free(out_buff,MYF(MY_WME)); -} - - /**************************************************************************** - Replace results for a column -*****************************************************************************/ + * Handle replacement of strings + ****************************************************************************/ -static void free_replace_column() +#define PC_MALLOC 256 /* Bytes for pointers */ +#define PS_MALLOC 512 /* Bytes for data */ + +int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name) { - uint i; - for (i=0 ; i < max_replace_column ; i++) + uint i,length,old_count; + byte *new_pos; + const char **new_array; + DBUG_ENTER("insert_pointer_name"); + + if (! pa->typelib.count) { - if (replace_column[i]) + if (!(pa->typelib.type_names=(const char **) + my_malloc(((PC_MALLOC-MALLOC_OVERHEAD)/ + (sizeof(my_string)+sizeof(*pa->flag))* + (sizeof(my_string)+sizeof(*pa->flag))),MYF(MY_WME)))) + DBUG_RETURN(-1); + if (!(pa->str= (byte*) my_malloc((uint) (PS_MALLOC-MALLOC_OVERHEAD), + MYF(MY_WME)))) { - my_free(replace_column[i], 0); - replace_column[i]= 0; + my_free((gptr) pa->typelib.type_names,MYF(0)); + DBUG_RETURN (-1); } + pa->max_count=(PC_MALLOC-MALLOC_OVERHEAD)/(sizeof(byte*)+ + sizeof(*pa->flag)); + pa->flag= (int7*) (pa->typelib.type_names+pa->max_count); + pa->length=0; + pa->max_length=PS_MALLOC-MALLOC_OVERHEAD; + pa->array_allocs=1; } - max_replace_column= 0; -} - -/* - Get arguments for replace_columns. The syntax is: - replace-column column_number to_string [column_number to_string ...] - Where each argument may be quoted with ' or " - A argument may also be a variable, in which case the value of the - variable is replaced. -*/ - -static void get_replace_column(struct st_query *q) -{ - char *from=q->first_argument; - char *buff,*start; - DBUG_ENTER("get_replace_columns"); - - free_replace_column(); - if (!*from) - die("Missing argument in %s", q->query); - - /* Allocate a buffer for results */ - start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); - while (*from) + length=(uint) strlen(name)+1; + if (pa->length+length >= pa->max_length) { - char *to; - uint column_number; - - to= get_string(&buff, &from, q); - if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS) - die("Wrong column number to replace_column in '%s'", q->query); - if (!*from) - die("Wrong number of arguments to replace_column in '%s'", q->query); - to= get_string(&buff, &from, q); - my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR); - replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE)); - set_if_bigger(max_replace_column, column_number); - } - my_free(start, MYF(0)); - q->last_argument= q->end; -} - -#if defined(__NETWARE__) || defined(__WIN__) -/* - Substitute environment variables with text. - - SYNOPSIS - subst_env_var() - arg String that should be substitute - - DESCRIPTION - This function takes a string as an input and replaces the - environment variables, that starts with '$' character, with it value. - - NOTES - Return string must be freed with my_free() - - RETURN - String with environment variables replaced. -*/ - -static char *subst_env_var(const char *str) -{ - char *result; - char *pos; - - result= pos= my_malloc(MAX_QUERY, MYF(MY_FAE)); - while (*str) - { - /* - need this only when we want to provide the functionality of - escaping through \ 'backslash' - if ((result == pos && *str=='$') || - (result != pos && *str=='$' && str[-1] !='\\')) - */ - if (*str == '$') + if (!(new_pos= (byte*) my_realloc((gptr) pa->str, + (uint) (pa->max_length+PS_MALLOC), + MYF(MY_WME)))) + DBUG_RETURN(1); + if (new_pos != pa->str) { - char env_var[256], *env_pos= env_var, *subst; - - /* Search for end of environment variable */ - for (str++; - *str && !isspace(*str) && *str != '\\' && *str != '/' && - *str != '$'; - str++) - *env_pos++= *str; - *env_pos= 0; - - if (!(subst= getenv(env_var))) - { - my_free(result, MYF(0)); - die("MYSQLTEST.NLM: Environment variable %s is not defined", - env_var); - } - - /* get the string to be substitued for env_var */ - pos= strmov(pos, subst); - /* Process delimiter in *str again */ + my_ptrdiff_t diff=PTR_BYTE_DIFF(new_pos,pa->str); + for (i=0 ; i < pa->typelib.count ; i++) + pa->typelib.type_names[i]= ADD_TO_PTR(pa->typelib.type_names[i],diff, + char*); + pa->str=new_pos; } - else - *pos++= *str++; + pa->max_length+=PS_MALLOC; } - *pos= 0; - return result; -} + if (pa->typelib.count >= pa->max_count-1) + { + int len; + pa->array_allocs++; + len=(PC_MALLOC*pa->array_allocs - MALLOC_OVERHEAD); + if (!(new_array=(const char **) my_realloc((gptr) pa->typelib.type_names, + (uint) len/ + (sizeof(byte*)+sizeof(*pa->flag))* + (sizeof(byte*)+sizeof(*pa->flag)), + MYF(MY_WME)))) + DBUG_RETURN(1); + pa->typelib.type_names=new_array; + old_count=pa->max_count; + pa->max_count=len/(sizeof(byte*) + sizeof(*pa->flag)); + pa->flag= (int7*) (pa->typelib.type_names+pa->max_count); + memcpy((byte*) pa->flag,(my_string) (pa->typelib.type_names+old_count), + old_count*sizeof(*pa->flag)); + } + pa->flag[pa->typelib.count]=0; /* Reset flag */ + pa->typelib.type_names[pa->typelib.count++]= pa->str+pa->length; + pa->typelib.type_names[pa->typelib.count]= NullS; /* Put end-mark */ + VOID(strmov(pa->str+pa->length,name)); + pa->length+=length; + DBUG_RETURN(0); +} /* insert_pointer_name */ -/* - popen replacement for Netware +/* free pointer array */ - SYNPOSIS - my_popen() - name Command to execute (with possible env variables) - mode Mode for popen. +void free_pointer_array(POINTER_ARRAY *pa) +{ + if (pa->typelib.count) + { + pa->typelib.count=0; + my_free((gptr) pa->typelib.type_names,MYF(0)); + pa->typelib.type_names=0; + my_free((gptr) pa->str,MYF(0)); + } +} /* free_pointer_array */ - NOTES - Environment variable expansion does not take place for popen function - on NetWare, so we use this function to wrap around popen to do this. - For the moment we ignore 'mode' and always use 'r0' +/* Functions that uses replace and replace_regex */ - RETURN - # >= 0 File handle - -1 Error -*/ - -#undef popen /* Remove wrapper */ -#ifdef __WIN__ -#define popen _popen /* redefine for windows */ +/* Append the string to ds, with optional replace */ +void replace_dynstr_append_mem(DYNAMIC_STRING *ds, + const char *val, int len) +{ +#ifdef __WIN__ + fix_win_paths(val, len); #endif -FILE *my_popen(const char *cmd, const char *mode __attribute__((unused))) -{ - char *subst_cmd; - FILE *res_file; + if (glob_replace_regex) + { + /* Regex replace */ + if (!multi_reg_replace(glob_replace_regex, (char*)val)) + { + val= glob_replace_regex->buf; + len= strlen(val); + } + } - subst_cmd= subst_env_var(cmd); - res_file= popen(subst_cmd, "r0"); - my_free(subst_cmd, MYF(0)); - return res_file; + if (glob_replace) + { + /* Normal replace */ + replace_strings_append(glob_replace, ds, val, len); + } + else + dynstr_append_mem(ds, val, len); } -#endif /* __NETWARE__ or __WIN__*/ + +/* Append zero-terminated string to ds, with optional replace */ +void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val) +{ + replace_dynstr_append_mem(ds, val, strlen(val)); +} + +/* Append uint to ds, with optional replace */ +void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) +{ + char buff[22]; /* This should be enough for any int */ + char *end= longlong10_to_str(val, buff, 10); + replace_dynstr_append_mem(ds, buff, end - buff); +} + + diff --git a/mysql-test/include/have_multi_ndb.inc b/mysql-test/include/have_multi_ndb.inc index ec1a93311fb..844c4d78774 100644 --- a/mysql-test/include/have_multi_ndb.inc +++ b/mysql-test/include/have_multi_ndb.inc @@ -9,8 +9,10 @@ disable_query_log; drop table if exists t1, t2; --enable_warnings flush tables; -@r/have_ndb.require show variables like "have_ndbcluster"; -# @r/server_id.require show variables like "server_id"; +--require r/have_ndb.require +show variables like "have_ndbcluster"; +#--require r/server_id.require +#show variables like "server_id"; enable_query_log; # Check that server2 has NDB support @@ -20,8 +22,10 @@ disable_query_log; drop table if exists t1, t2; --enable_warnings flush tables; -@r/have_ndb.require show variables like "have_ndbcluster"; -# @r/server_id1.require show variables like "server_id"; +--require r/have_ndb.require +show variables like "have_ndbcluster"; +#--require r@r/server_id1.require +#show variables like "server_id"; enable_query_log; # Set the default connection to 'server1' diff --git a/mysql-test/include/master-slave.inc b/mysql-test/include/master-slave.inc index 5ec4b4379f8..9ef5489f346 100644 --- a/mysql-test/include/master-slave.inc +++ b/mysql-test/include/master-slave.inc @@ -8,7 +8,8 @@ connection slave; --disable_warnings stop slave; --enable_warnings -@r/slave-stopped.result show status like 'Slave_running'; +--require r/slave-stopped.result +show status like 'Slave_running'; connection master; --disable_warnings drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; @@ -21,7 +22,8 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings start slave; -@r/slave-running.result show status like 'Slave_running'; +--require r/slave-running.result +show status like 'Slave_running'; # Set the default connection to 'master' connection master; diff --git a/mysql-test/include/ps_query.inc b/mysql-test/include/ps_query.inc index 9a413bff2f3..a2eac09d121 100644 --- a/mysql-test/include/ps_query.inc +++ b/mysql-test/include/ps_query.inc @@ -52,7 +52,6 @@ execute stmt1; ##### parameter used for keyword like SELECT (must fail) set @arg00='SELECT' ; -# mysqltest gives no output for the next statement, Why ?? --error 1064 @arg00 a from t1 where a=1; --error 1064 diff --git a/mysql-test/include/show_msg.inc b/mysql-test/include/show_msg.inc new file mode 100755 index 00000000000..659dce14686 --- /dev/null +++ b/mysql-test/include/show_msg.inc @@ -0,0 +1,25 @@ +#### include/show_msg.inc +# +# This file writes the value set in @message into the +# a protocol file as part of executing a test sequence +# +# Usage: +# Add the following to any *.test file: +# : +# let $message= ; +# --source include/show_msg.inc +# : +# +# Attention: +# - Please do not write any spaces between $message and the "=", because the +# assignment will not work. +# - Be careful with single quotes. They must be escaped like "''" or "\'". +# +# "include/show_msg80.inc" contains a detailed description and examples. + +--disable_query_log +eval SET @utf8_message = CONVERT('$message' using utf8); +select @utf8_message as "" +union +select repeat(CONVERT('-' using utf8),char_length(@utf8_message)); +--enable_query_log diff --git a/mysql-test/include/show_msg80.inc b/mysql-test/include/show_msg80.inc new file mode 100755 index 00000000000..42fb35edbcc --- /dev/null +++ b/mysql-test/include/show_msg80.inc @@ -0,0 +1,118 @@ +#### include/show_msg80.inc +# +# This file writes the value set in @message into the a protocol file as part +# of executing a test sequence with a dash line that is fixed on 80 characters. +# +# This can be used in the case of long messages, multi line messages that +# exceed 80 or if an 80 char line is desired for short messages. +# +# Usage: +# Add the following to any *.test file: +# : +# let $message= ; +# --source include/show_msg80.inc +# : +# +# Attention: +# - Please do not write any spaces between $message and the "=", because the +# assignment will not work. +# - Be careful with single quotes within the value. They must be escaped like +# "''" or "\'". +# - Do not keep the value between single quotes. +# +# +# Content of "$message" and protocol output depending on the assignment: +# ---------------------------------------------------------------------- +# +# I is assumed, that the value is not kept between double quotes. +# +# first character after "$message=", +# where the content is not (space or tab) +# first character after beginning of the line, +# where the content is not (space or tab) +# last char before ";" +# | beginning or end of line +# +# script: let $message= | +# | | +# |................| +# | ; +# content: " +# ...." +# protocol output: || +# || +# |.....| +# || +# |--- 80 dashes ---| +# +# Attention: +# and set to characters like "-$#" which are also used +# to start comments, options and the names of mysqltest variables +# lead to syntax errors or mangled messages. +# +# +# Examples of messages: +# --------------------- +# +# Variant1 (ease of use): +# Several lines with indentation kept between double quotes +# script: |let $message= +# |" Testcase 3.1 : Ensure that Pi is not an| +# | integer number.| +# | Third line"; +# protocol: |" Testcase 3.1 : Ensure that Pi is not an| +# | integer number.| +# | Third line"| +# |------ 80 dashes ----| +# +# Please mention that +# - the '"' preserves the indentation. +# - it is easy to write the script lines to get a fine indentation, +# if the value starts at the beginning of a new line +# - the '"' is printed +# - there are the least or no problems with characters like "-#$" +# +# +# Variant 2 (grep the messages from the protocol is easy): +# Several lines with indentation + auxiliary character (".") +# at the (non tab or space) beginning of every message line +# script: |let $message= . Testcase 3.1 : Ensure that Pi is not an| +# | . integer number.| +# | . Third line; +# protocol: |. Testcase 3.1 : Ensure that Pi is not an| +# |. integer number.| +# |. Third line| +# |------ 80 dashes ----| +# Please mention that +# - the auxiliary character preserves the indentation. +# - it is easy to write the script lines to get a fine indentation +# - the auxiliary character is printed +# - it is recommended to use "." as auxiliary character +# - auxiliary characters like "-'$#" cause problems +# +# +# +# Bad variant1: Several lines with lost indentation +# script: |let $message= Here is message line 1 +# | message line 2; +# protocol: |Here is message line 1| +# |message line 2| +# |------ 80 dashes ----| +# Please mention, that the leading spaces of the message lines disappeared. +# +# Bad variant2: Several lines leading to a syntax error, because of "-" +# script: |let $message= - This is a message +# | - with a second and +# | - third line; +# protocol: | - third line;; +# |ERROR 42000: You have an error ... near '- third line' +# + several following errors +# +# + +--disable_query_log +eval SET @utf8_message = CONVERT('$message' using utf8); +select @utf8_message as "" +union +select repeat(CONVERT('-' using utf8),80); +--enable_query_log diff --git a/mysql-test/r/check.result b/mysql-test/r/check.result index ecaa13642bd..26dbc9e345c 100644 --- a/mysql-test/r/check.result +++ b/mysql-test/r/check.result @@ -1,6 +1,6 @@ drop table if exists t1; create table t1(n int not null, key(n), key(n), key(n), key(n)); - check table t1 extended; +check table t1 extended; insert into t1 values (200000); Table Op Msg_type Msg_text test.t1 check status OK diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index 68c86b80e60..b9c1e3e5542 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -18,6 +18,10 @@ time_zone_transition_type user show tables; Tables_in_test +connect(localhost,root,z,test2,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES) +connect(localhost,root,z,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'root'@'localhost' (using password: YES) grant ALL on *.* to test@localhost identified by "gambling"; grant ALL on *.* to test@127.0.0.1 identified by "gambling"; show tables; @@ -39,6 +43,14 @@ time_zone_transition_type user show tables; Tables_in_test +connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) +connect(localhost,test,,"",MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) +connect(localhost,test,zorro,test2,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) +connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) update mysql.user set password=old_password("gambling2") where user=_binary"test"; flush privileges; set password=""; @@ -64,6 +76,14 @@ time_zone_transition_type user show tables; Tables_in_test +connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) +connect(localhost,test,,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) +connect(localhost,test,zorro,test2,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) +connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET); +ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) delete from mysql.user where user=_binary"test"; flush privileges; create table t1 (id integer not null auto_increment primary key); diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index 384bdc1214b..83b8b769f67 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -9,13 +9,13 @@ n flush tables with read lock; drop table t2; ERROR HY000: Table 't2' was locked with a READ lock and can't be updated - drop table t2; +drop table t2; unlock tables; create database mysqltest; create table mysqltest.t1(n int); insert into mysqltest.t1 values (23); flush tables with read lock; - drop database mysqltest; +drop database mysqltest; select * from mysqltest.t1; n 23 diff --git a/mysql-test/r/flush_block_commit.result b/mysql-test/r/flush_block_commit.result index 2e9f1920937..d5b10868358 100644 --- a/mysql-test/r/flush_block_commit.result +++ b/mysql-test/r/flush_block_commit.result @@ -5,7 +5,7 @@ insert into t1 values(1); flush tables with read lock; select * from t1; a - commit; +commit; select * from t1; a unlock tables; @@ -14,8 +14,8 @@ select * from t1 for update; a 1 begin; - select * from t1 for update; - flush tables with read lock; +select * from t1 for update; +flush tables with read lock; commit; a 1 diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index adf2035173f..246713489b4 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -69,7 +69,7 @@ FROM t1 WHERE conn = 'default'; IS_USED_LOCK('bug16501') = connection_id 1 - SELECT GET_LOCK('bug16501',600); +SELECT GET_LOCK('bug16501',600); SELECT IS_USED_LOCK('bug16501') = CONNECTION_ID(); IS_USED_LOCK('bug16501') = CONNECTION_ID() 1 diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index c047dc033c6..36d4e51119d 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -123,12 +123,12 @@ drop database mysqltest_1; set password = password("changed"); ERROR 42000: Access denied for user ''@'localhost' to database 'mysql' lock table mysql.user write; - flush privileges; - grant all on *.* to 'mysqltest_1'@'localhost'; +flush privileges; +grant all on *.* to 'mysqltest_1'@'localhost'; unlock tables; lock table mysql.user write; - set password for 'mysqltest_1'@'localhost' = password(''); - revoke all on *.* from 'mysqltest_1'@'localhost'; +set password for 'mysqltest_1'@'localhost' = password(''); +revoke all on *.* from 'mysqltest_1'@'localhost'; unlock tables; drop user 'mysqltest_1'@'localhost'; insert into mysql.user (user, host) values diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 9b0c6dbc263..e88d359e0ef 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -452,7 +452,7 @@ handler t1 read first; c1 1 send the below to another connection, do not wait for the result - optimize table t1; +optimize table t1; proceed with the normal connection handler t1 read next; c1 diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index eff59b102de..2a88f1ce3a8 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -24,7 +24,7 @@ create table t2 (id int unsigned not null); insert into t2 select id from t1; create table t3 (kill_id int); insert into t3 values(connection_id()); - select id from t1 where id in (select distinct id from t2); +select id from t1 where id in (select distinct id from t2); select ((@id := kill_id) - kill_id) from t3; ((@id := kill_id) - kill_id) 0 diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 9eedbf50064..59b683b1917 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -2,8 +2,8 @@ drop table if exists t1,t2; create table t1(n int); insert into t1 values (1); lock tables t1 write; - update low_priority t1 set n = 4; - select n from t1; +update low_priority t1 set n = 4; +select n from t1; unlock tables; n 4 @@ -11,8 +11,8 @@ drop table t1; create table t1(n int); insert into t1 values (1); lock tables t1 read; - update low_priority t1 set n = 4; - select n from t1; +update low_priority t1 set n = 4; +select n from t1; unlock tables; n 1 @@ -23,7 +23,7 @@ insert into t1 values(1,1); insert into t1 values(2,2); insert into t2 values(1,2); lock table t1 read; - update t1,t2 set c=a where b=d; +update t1,t2 set c=a where b=d; select c from t2; c 2 @@ -32,7 +32,7 @@ drop table t2; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write; - insert t1 select * from t2; +insert t1 select * from t2; drop table t2; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; diff --git a/mysql-test/r/mix_innodb_myisam_binlog.result b/mysql-test/r/mix_innodb_myisam_binlog.result index 8cf99e8d623..f8de0336e63 100644 --- a/mysql-test/r/mix_innodb_myisam_binlog.result +++ b/mysql-test/r/mix_innodb_myisam_binlog.result @@ -193,7 +193,7 @@ select (@before:=unix_timestamp())*0; (@before:=unix_timestamp())*0 0 begin; - select * from t1 for update; +select * from t1 for update; insert into t2 values (20); ERROR HY000: Lock wait timeout exceeded; try restarting transaction select (@after:=unix_timestamp())*0; diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 091a3c0547d..7276397bdc7 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -16,7 +16,7 @@ otto mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22... select friedrich from (select 1 as otto) as t1; ERROR 42S22: Unknown column 'friedrich' in 'field list' -mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22 instead of 00000... +mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000... select otto from (select 1 as otto) as t1; otto 1 @@ -133,8 +133,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist select 1146 as "after_!errno_masked_error" ; after_!errno_masked_error 1146 -mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146 instead of 1000... -mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146 instead of 1000... +mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1000... garbage ; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 select 1064 as "after_--enable_abort_on_error" ; @@ -142,8 +141,7 @@ after_--enable_abort_on_error 1064 select 3 from t1 ; ERROR 42S02: Table 'test.t1' doesn't exist -mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146 instead of 1064... -mysqltest: At line 1: query 'select 3 from t1' failed: 1146: Table 'test.t1' doesn't exist +mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1064... hello hello ;;;;;;;; @@ -151,7 +149,24 @@ hello mysqltest: At line 1: End of line junk detected: "6" mysqltest: At line 1: End of line junk detected: "6" mysqltest: At line 1: Missing delimiter +mysqltest: At line 1: End of line junk detected: "sleep 7 +# Another comment +" mysqltest: At line 1: Extra delimiter ";" found +mysqltest: At line 1: Extra delimiter ";" found +mysqltest: At line 1: Missing argument(s) to 'error' +mysqltest: At line 1: Missing argument(s) to 'error' +mysqltest: At line 1: The sqlstate definition must start with an uppercase S +mysqltest: At line 1: The error name definition must start with an uppercase E +mysqltest: At line 1: Invalid argument to error: '9eeeee' - the errno may only consist of digits[0-9] +mysqltest: At line 1: Invalid argument to error: '1sssss' - the errno may only consist of digits[0-9] +mysqltest: At line 1: The sqlstate must be exactly 5 chars long +mysqltest: At line 1: The sqlstate may only consist of digits[0-9] and _uppercase_ letters +mysqltest: At line 1: The sqlstate must be exactly 5 chars long +mysqltest: At line 1: Not available in mysqltest for MySQL 4.1.22 +mysqltest: At line 1: Invalid argument to error: '999e9' - the errno may only consist of digits[0-9] +mysqltest: At line 1: Invalid argument to error: '9b' - the errno may only consist of digits[0-9] +mysqltest: At line 1: Too many errorcodes specified MySQL "MySQL" MySQL: The world''s most popular open source database @@ -166,8 +181,8 @@ source database - most popular open - source database - MySQL: The world''s --- most popular open --- source database +-- most popular +-- open source database # MySQL: The --world''s # most popular @@ -193,14 +208,20 @@ source database # source database -- MySQL: The -- world''s most --- popular open --- source database +-- popular +-- open source database # MySQL: The - world''s most -- popular open # source database -'$message' -"$message" +'# MySQL: The +- world''s most +-- popular open +# source database' +"# MySQL: The +- world''s most +-- popular open +# source database" hej hej hej @@ -209,21 +230,32 @@ hej a long variable content a long variable content -a long $where variable content +a long a long variable content variable content +a long \$where variable content +banana = banana +Not a banana: ba\$cat\$cat mysqltest: At line 1: Missing arguments to let mysqltest: At line 1: Missing variable name in let -mysqltest: At line 1: Variable name in hi=hi does not start with '$' mysqltest: At line 1: Missing assignment operator in let mysqltest: At line 1: Missing assignment operator in let -mysqltest: At line 1: Missing arguments to let +mysqltest: At line 1: Missing assignment operator in let +mysqltest: At line 1: Missing variable name in let mysqltest: At line 1: Missing variable name in let -mysqltest: At line 1: Variable name in =hi does not start with '$' mysqltest: At line 1: Missing assignment operator in let -mysqltest: At line 1: Missing file name in source +# Execute: --echo # success: $success +# success: 1 +# Execute: echo # success: $success ; +# success: 1 +# The next two variants work fine and expand the content of $success +# Execute: --echo $success +1 +# Execute: echo $success ; +1 +mysqltest: At line 1: Missing required argument 'filename' to command 'source' mysqltest: At line 1: Could not open file ./non_existingFile -mysqltest: In included file "./var/tmp/recursive.sql": At line 1: Source directives are nesting too deep -mysqltest: In included file "./var/tmp/error.sql": At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 +mysqltest: In included file "MYSQLTEST_VARDIR/tmp/recursive.sql": At line 1: Source directives are nesting too deep +mysqltest: In included file "MYSQLTEST_VARDIR/tmp/error.sql": At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 2 = outer loop variable after while here is the sourced script @@ -288,8 +320,8 @@ mysqltest: At line 1: Invalid argument to real_sleep "abc" 101 hej 1 -mysqltest: At line 1: Missing arguments to inc -mysqltest: At line 1: First argument to inc must be a variable (start with $) +mysqltest: At line 1: Missing argument to inc +mysqltest: At line 1: The argument to inc must be a variable (start with $) mysqltest: At line 1: End of line junk detected: "1000" 4 4 @@ -298,27 +330,31 @@ mysqltest: At line 1: End of line junk detected: "1000" 99 hej -1 -mysqltest: At line 1: Missing arguments to dec -mysqltest: At line 1: First argument to dec must be a variable (start with $) +mysqltest: At line 1: Missing argument to dec +mysqltest: At line 1: The argument to dec must be a variable (start with $) mysqltest: At line 1: End of line junk detected: "1000" mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: system command 'false' failed +system command 'NonExistsinfComamdn 2> /dev/null' failed test test2 test3 test4 +Counter is greater than 0, (counter=10) +Counter is not 0, (counter=0) 1 -mysqltest: In included file "./include/mysqltest_while.inc": At line 64: Nesting too deeply +Testing while with not +mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest_while.inc": At line 64: Nesting too deeply mysqltest: At line 1: missing '(' in while mysqltest: At line 1: missing ')' in while mysqltest: At line 1: Missing '{' after while. Found "dec $i" mysqltest: At line 1: Stray '}' - end of block before beginning mysqltest: At line 1: Stray 'end' command - end of block before beginning -mysqltest: At line 1: query '' failed: 1065: Query was empty +mysqltest: At line 1: query '{' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '{' at line 1 mysqltest: At line 1: Missing '{' after while. Found "echo hej" mysqltest: At line 3: Missing end of block -mysqltest: At line 1: Missing newline between while and '{' +mysqltest: At line 3: Missing end of block mysqltest: At line 1: missing '(' in if mysqltest: At line 1: Stray 'end' command - end of block before beginning select "b" bs col1, "c" bs col2; @@ -331,6 +367,7 @@ mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_re mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a;' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a ' +OK mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a b c' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a b c ' select "a" as col1, "c" as col2; @@ -347,6 +384,18 @@ mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 mysqltest: At line 1: Invalid integer argument "10!" mysqltest: At line 1: End of line junk detected: "!" mysqltest: At line 1: Invalid integer argument "a" +mysqltest: At line 1: Missing required argument 'connection name' to command 'connect' +mysqltest: At line 1: Missing required argument 'connection name' to command 'connect' +mysqltest: At line 1: Missing required argument 'host' to command 'connect' +mysqltest: At line 1: Missing required argument 'host' to command 'connect' +mysqltest: At line 1: query 'connect con2,localhost,root,,illegal_db' failed: 1049: Unknown database 'illegal_db' +mysqltest: At line 1: Illegal argument for port: 'illegal_port' +mysqltest: At line 1: Illegal option to connect: SMTP +OK +mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 7: Connection limit exhausted, you can have max 128 connections +mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 3: connection 'test_con1' not found in connection pool +mysqltest: In included file "MYSQLTEST_VARDIR/tmp/mysqltest.sql": At line 2: Connection test_con1 already exists +connect(localhost,root,,test,MASTER_PORT,MASTER_SOCKET); Output from mysqltest-x.inc Output from mysqltest-x.inc Output from mysqltest-x.inc @@ -358,3 +407,98 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp SELECT 1 as a; a 1 +select 1 as `a'b`, 2 as `a"b`; +a'b a"b +1 2 +select 'aaa\\','aa''a',"aa""a"; +aaa\ aa'a aa"a +aaa\ aa'a aa"a + +Here comes a message +-------------------- + +root@localhost +-------------- + +"Here comes a very very long message that + - is longer then 80 characters and + - consists of several lines" +-------------------------------------------------------------------------------- + +. Here comes a very very long message that +. - is longer then 80 characters and +. - consists of several lines +-------------------------------------------------------------------------------- +this will be executed +this will be executed +mysqltest: Result length mismatch +mysqltest: The test didn't produce any output +Failing multi statement query +mysqltest: At line 3: query 'create table t1 (a int primary key); +insert into t1 values (1); +select 'select-me'; +insertz 'error query'' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz 'error query'' at line 1 +drop table t1; +mysqltest: At line 3: query 'create table t1 (a int primary key); +insert into t1 values (1); +select 'select-me'; +insertz 'error query'' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz 'error query'' at line 1 +drop table t1; +Multi statement using expected error +create table t1 (a int primary key); +insert into t1 values (1); +select 'select-me'; +insertz error query|||| +select-me +select-me +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz error query' at line 1 +drop table t1; +drop table t1; +sleep; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sleep' at line 1 +sleep; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sleep' at line 1 +; +ERROR 42000: Query was empty +select "b" as col1, "c" as col2; +col1 col2 +b c +select "b" as col1, "b" as col2, "c" as col3; +col1 col2 col3 +b b c +seled "b" bs col1, "d" bs col2; +col1 col2 +b d +select "raspberry and strawberry","blackberry","tomato"; +raspberry and strawberry blackberry tomato +raspberry and strawberry blackberry tomato +mysqltest: At line 1: Error parsing replace_regex "a" +mysqltest: At line 1: Error parsing replace_regex "a;" +mysqltest: At line 1: Error parsing replace_regex "a" +mysqltest: At line 1: Error parsing replace_regex "a " +mysqltest: At line 1: Error parsing replace_regex "a b" +mysqltest: At line 1: Error parsing replace_regex "/a b c" +mysqltest: At line 1: Error parsing replace_regex "/a /b c " +create table t1 (a int, b int); +insert into t1 values (1,3); +insert into t1 values (2,4); +select * from t1; +a D +1 1 +1 4 +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 +mysqltest: At line 1: End of line junk detected: "write_file filename "; +" +mysqltest: At line 1: Missing required argument 'filename' to command 'file_exists' +mysqltest: At line 1: Missing required argument 'from_file' to command 'copy_file' +mysqltest: At line 1: Missing required argument 'to_file' to command 'copy_file' +hello +hello +hello +mysqltest: At line 1: Max delimiter length(16) exceeded +hello +hello +End of tests diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result index 4b655cfb854..771245c3713 100644 --- a/mysql-test/r/ps_2myisam.result +++ b/mysql-test/r/ps_2myisam.result @@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result index 4d2a62887d6..8435bb348f4 100644 --- a/mysql-test/r/ps_3innodb.result +++ b/mysql-test/r/ps_3innodb.result @@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result index a4919b664c4..d6876825aa9 100644 --- a/mysql-test/r/ps_4heap.result +++ b/mysql-test/r/ps_4heap.result @@ -86,6 +86,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result index f98cc1b3cdf..f2d459c6769 100644 --- a/mysql-test/r/ps_5merge.result +++ b/mysql-test/r/ps_5merge.result @@ -128,6 +128,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; @@ -3142,6 +3144,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result index acd7f45de95..3e16923c46f 100644 --- a/mysql-test/r/ps_6bdb.result +++ b/mysql-test/r/ps_6bdb.result @@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result index 27a1ea0925d..baceb1e4a9e 100644 --- a/mysql-test/r/ps_7ndb.result +++ b/mysql-test/r/ps_7ndb.result @@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday set @arg00='SELECT' ; +@arg00 a from t1 where a=1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1 prepare stmt1 from ' ? a from t1 where a=1 '; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 set @arg00=1 ; diff --git a/mysql-test/r/rename.result b/mysql-test/r/rename.result index 76c0f4422fe..964babb1228 100644 --- a/mysql-test/r/rename.result +++ b/mysql-test/r/rename.result @@ -43,7 +43,7 @@ Note 1051 Unknown table 't4' CREATE TABLE t1 (a int); CREATE TABLE t3 (a int); FLUSH TABLES WITH READ LOCK; - RENAME TABLE t1 TO t2, t3 to t4; +RENAME TABLE t1 TO t2, t3 to t4; show tables; Tables_in_test t1 diff --git a/mysql-test/r/rpl000001.result b/mysql-test/r/rpl000001.result index eef986d8f8c..1bce3b1b235 100644 --- a/mysql-test/r/rpl000001.result +++ b/mysql-test/r/rpl000001.result @@ -59,7 +59,7 @@ create table t2(id int); insert into t2 values(connection_id()); create temporary table t3(n int); insert into t3 select get_lock('crash_lock%20C', 1) from t2; - update t1 set n = n + get_lock('crash_lock%20C', 2); +update t1 set n = n + get_lock('crash_lock%20C', 2); select (@id := id) - id from t2; (@id := id) - id 0 diff --git a/mysql-test/r/rpl000018.result b/mysql-test/r/rpl000018.result deleted file mode 100644 index b71f6492b97..00000000000 --- a/mysql-test/r/rpl000018.result +++ /dev/null @@ -1,14 +0,0 @@ -reset master; -reset slave; -start slave; -show binary logs; -Log_name -master-bin.000001 -master-bin.000002 -drop table if exists t1; -create table t1(n int); -insert into t1 values (3351); -select * from t1; -n -3351 -drop table t1; diff --git a/mysql-test/r/rpl_chain_temp_table.result b/mysql-test/r/rpl_chain_temp_table.result deleted file mode 100644 index 5ece80565c7..00000000000 --- a/mysql-test/r/rpl_chain_temp_table.result +++ /dev/null @@ -1,30 +0,0 @@ -slave stop; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -slave start; -reset master; -change master to master_host='127.0.0.1',master_port=9307, master_user='root'; -start slave; -create temporary table t1 (a int); -create temporary table t1 (a int); -show status like 'slave_open_temp_tables'; -Variable_name Value -Slave_open_temp_tables 2 -create temporary table t1 (a int); -create temporary table t1 (a int); -show status like 'slave_open_temp_tables'; -Variable_name Value -Slave_open_temp_tables 4 -stop slave; -insert into t1 values(1); -create table t2 as select * from t1; -start slave; -show status like 'slave_open_temp_tables'; -Variable_name Value -Slave_open_temp_tables 4 -select * from t2; -a -1 -drop table t2; diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result index 4a562dbfc70..789ca72cd61 100644 --- a/mysql-test/r/rpl_error_ignored_table.result +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -20,7 +20,7 @@ create table t2 (a int primary key); insert into t2 values(1); create table t3 (id int); insert into t3 values(connection_id()); - update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); +update t2 set a = a + 1 + get_lock('crash_lock%20C', 10); select (@id := id) - id from t3; (@id := id) - id 0 diff --git a/mysql-test/r/rpl_failsafe.result b/mysql-test/r/rpl_failsafe.result deleted file mode 100644 index 956555f9318..00000000000 --- a/mysql-test/r/rpl_failsafe.result +++ /dev/null @@ -1,34 +0,0 @@ -stop slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -reset master; -reset slave; -drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -start slave; -show variables like 'rpl_recovery_rank'; -Variable_name Value -rpl_recovery_rank 1 -show status like 'Rpl_status'; -Variable_name Value -Rpl_status AUTH_MASTER -create table t1(n int); -drop table t1; -show variables like 'rpl_recovery_rank'; -Variable_name Value -rpl_recovery_rank 2 -show status like 'Rpl_status'; -Variable_name Value -Rpl_status ACTIVE_SLAVE -start slave; -show variables like 'rpl_recovery_rank'; -Variable_name Value -rpl_recovery_rank 3 -show status like 'Rpl_status'; -Variable_name Value -Rpl_status ACTIVE_SLAVE -start slave; -show variables like 'rpl_recovery_rank'; -Variable_name Value -rpl_recovery_rank 4 -show status like 'Rpl_status'; -Variable_name Value -Rpl_status ACTIVE_SLAVE diff --git a/mysql-test/r/rpl_heap.result b/mysql-test/r/rpl_heap.result deleted file mode 100644 index 1facbcb7676..00000000000 --- a/mysql-test/r/rpl_heap.result +++ /dev/null @@ -1,29 +0,0 @@ -reset master; -drop table if exists t1; -create table t1 type=HEAP select 10 as a; -insert into t1 values(11); -show binlog events from 79; -Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.001 79 Query 1 79 use `test`; create table t1 type=HEAP select 10 as a -master-bin.001 154 Query 1 154 use `test`; insert into t1 values(11) -reset slave; -start slave; -show create table t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` bigint(2) NOT NULL default '0' -) TYPE=HEAP -select * from t1; -a -10 -11 -select * from t1; -a -select * from t1 limit 10; -a -show binlog events in 'master-bin.002' from 79; -Log_name Pos Event_type Server_id Orig_log_pos Info -master-bin.002 79 Query 1 79 use `test`; DELETE FROM `test`.`t1` -select * from t1; -a -drop table t1; diff --git a/mysql-test/r/rpl_master_pos_wait.result b/mysql-test/r/rpl_master_pos_wait.result index e92d1ffa361..84f2b0bd91e 100644 --- a/mysql-test/r/rpl_master_pos_wait.result +++ b/mysql-test/r/rpl_master_pos_wait.result @@ -12,7 +12,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used Warnings: Note 1003 select sql_no_cache master_pos_wait(_latin1'master-bin.999999',0,2) AS `master_pos_wait('master-bin.999999',0,2)` - select master_pos_wait('master-bin.999999',0); +select master_pos_wait('master-bin.999999',0); stop slave sql_thread; master_pos_wait('master-bin.999999',0) NULL diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index f5abc4ed42a..84b5a42d173 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -2697,8 +2697,7 @@ select (1,2,3) = (select * from t1); ERROR 21000: Operand should contain 3 column(s) select (select * from t1) = (1,2,3); ERROR 21000: Operand should contain 2 column(s) -drop table t1 -#; +drop table t1; CREATE TABLE `t1` ( `itemid` bigint(20) unsigned NOT NULL auto_increment, `sessionid` bigint(20) unsigned default NULL, diff --git a/mysql-test/r/synchronization.result b/mysql-test/r/synchronization.result index ad9443c86da..8b243fe29b2 100644 --- a/mysql-test/r/synchronization.result +++ b/mysql-test/r/synchronization.result @@ -1,5 +1,5 @@ CREATE TABLE t1 (x1 int); - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -7,7 +7,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -15,7 +15,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -23,7 +23,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -31,7 +31,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -39,7 +39,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -47,7 +47,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -55,7 +55,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -63,7 +63,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -71,7 +71,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -79,7 +79,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -87,7 +87,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -95,7 +95,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -103,7 +103,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -111,7 +111,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -119,7 +119,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -127,7 +127,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -135,7 +135,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -143,7 +143,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x1 x2 int; +ALTER TABLE t1 CHANGE x1 x2 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table @@ -151,7 +151,7 @@ t2 CREATE TABLE `t2` ( `xx` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t2; - ALTER TABLE t1 CHANGE x2 x1 int; +ALTER TABLE t1 CHANGE x2 x1 int; CREATE TABLE t2 LIKE t1; SHOW CREATE TABLE t2; Table Create Table diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 6b4b54fbb66..977377c0bc6 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -24,8 +24,7 @@ t3 CREATE TABLE `t3` ( `a` mediumtext, `b` mediumblob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -drop table t1,t2,t3 -#; +drop table t1,t2,t3; CREATE TABLE t1 (a char(257) default "hello"); ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT instead CREATE TABLE t2 (a blob default "hello"); diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index ff15d74e5ac..89e34f0c8e0 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -1,7 +1,6 @@ # This test is to check various cases of connections -# with right and wrong password, with and without database -# Unfortunately the check is incomplete as we can't handle errors on connect -# Also we can't connect without database +# with right and wrong password, with and without database +# Unfortunately the check is incomplete as we can't connect without database # This test makes no sense with the embedded server --source include/not_embedded.inc @@ -10,69 +9,73 @@ drop table if exists t1,t2; --enable_warnings + #connect (con1,localhost,root,,""); #show tables; connect (con1,localhost,root,,mysql); show tables; -connect (con1,localhost,root,,test); +connect (con2,localhost,root,,test); show tables; -# Re enable this one day if error handling on connect will take place - -#connect (con1,localhost,root,z,test2); -#--error 1045 -#connect (con1,localhost,root,z,); -#--error 1045 +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,root,z,test2); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,root,z,); grant ALL on *.* to test@localhost identified by "gambling"; grant ALL on *.* to test@127.0.0.1 identified by "gambling"; # Now check this user with different databases - #connect (con1,localhost,test,gambling,""); #show tables; -connect (con1,localhost,test,gambling,mysql); +connect (con3,localhost,test,gambling,mysql); show tables; -connect (con1,localhost,test,gambling,test); +connect (con4,localhost,test,gambling,test); show tables; -# Re enable this one day if error handling on connect will take place - -#connect (con1,localhost,test,,test2); -#--error 1045 -#connect (con1,localhost,test,,""); -#--error 1045 -#connect (con1,localhost,test,zorro,test2); -#--error 1045 -#connect (con1,localhost,test,zorro,); -#--error 1045 +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,,test2); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,,""); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,zorro,test2); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,zorro,); # check if old password version also works update mysql.user set password=old_password("gambling2") where user=_binary"test"; flush privileges; -#connect (con1,localhost,test,gambling2,""); -#show tables; -connect (con1,localhost,test,gambling2,mysql); +connect (con10,localhost,test,gambling2,); +connect (con5,localhost,test,gambling2,mysql); +connection con5; set password=""; --error 1105 set password='gambling3'; set password=old_password('gambling3'); show tables; -connect (con1,localhost,test,gambling3,test); +connect (con6,localhost,test,gambling3,test); show tables; -# Re enable this one day if error handling on connect will take place - -#connect (con1,localhost,test,,test2); -#--error 1045 -#connect (con1,localhost,test,,); -#--error 1045 -#connect (con1,localhost,test,zorro,test2); -#--error 1045 -#connect (con1,localhost,test,zorro,); -#--error 1045 +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,,test2); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,,); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,zorro,test2); +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--error 1045 +connect (fail_con,localhost,test,zorro,); # remove user 'test' so that other tests which may use 'test' @@ -84,13 +87,13 @@ flush privileges; # # Bug#12517: Clear user variables and replication events before # closing temp tables in thread cleanup. -connect (con2,localhost,root,,test); -connection con2; +connect (con7,localhost,root,,test); +connection con7; create table t1 (id integer not null auto_increment primary key); create temporary table t2(id integer not null auto_increment primary key); set @id := 1; delete from t1 where id like @id; -disconnect con2; +disconnect con7; --sleep 5 connection default; drop table t1; diff --git a/mysql-test/t/init_file.test b/mysql-test/t/init_file.test index de6aca455bd..bbe0c4ff884 100644 --- a/mysql-test/t/init_file.test +++ b/mysql-test/t/init_file.test @@ -4,6 +4,7 @@ # # See mysql-test/std_data/init_file.dat and # mysql-test/t/init_file-master.opt for the actual test -# +# -# End of 4.1 tests +--echo ok +--echo End of 4.1 tests diff --git a/mysql-test/t/mysql_client_test.test b/mysql-test/t/mysql_client_test.test index 1225bf73009..2677e470289 100644 --- a/mysql-test/t/mysql_client_test.test +++ b/mysql-test/t/mysql_client_test.test @@ -8,8 +8,8 @@ # server or run mysql-test-run --debug mysql_client_test and check # var/log/mysql_client_test.trace ---disable_result_log ---exec echo $MYSQL_CLIENT_TEST --getopt-ll-test=25600M ---exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M +--exec echo "$MYSQL_CLIENT_TEST --getopt-ll-test=25600M" > $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1 +--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M >> $MYSQLTEST_VARDIR/log/mysql_client_test.log 2>&1 # End of 4.1 tests +echo ok; diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index a15a143e9f4..5b0df28981f 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1,3 +1,4 @@ +# This test should work in embedded server after mysqltest is fixed -- source include/not_embedded.inc # ============================================================================ @@ -26,7 +27,7 @@ # ---------------------------------------------------------------------------- # $mysql_errno contains the return code of the last command -# send to the server. +# sent to the server. # ---------------------------------------------------------------------------- # get $mysql_errno before the first statement # $mysql_errno should be -1 @@ -49,7 +50,7 @@ select otto from (select 1 as otto) as t1; # ---------------------------------------------------------------------------- # Negative case(statement): -# The dervied table t1 does not contain a column named 'friedrich' . +# The derived table t1 does not contain a column named 'friedrich' . # --> ERROR 42S22: Unknown column 'friedrich' in 'field list and # --> 1054: Unknown column 'friedrich' in 'field list' # ---------------------------------------------------------------------------- @@ -67,7 +68,7 @@ select friedrich from (select 1 as otto) as t1; # The following unmasked unsuccessful statement must give # 1. mysqltest gives a 'failed' # 2. does not produce a r/.reject file !!! -# PLEASE uncomment it and check it's effect +# PLEASE uncomment it and check its effect #select friedrich from (select 1 as otto) as t1; @@ -113,7 +114,7 @@ select friedrich from (select 1 as otto) as t1; # test cases for $mysql_errno # # $mysql_errno is a builtin variable of mysqltest and contains the return code -# of the last command send to the server. +# of the last command sent to the server. # # The following test cases often initialize $mysql_errno to 1064 by # a command with wrong syntax. @@ -216,7 +217,7 @@ garbage ; execute stmt; eval select $mysql_errno as "after_successful_execute" ; -# failing execute (table dropped) +# failing execute (table has been dropped) drop table t1; --error 1064 garbage ; @@ -248,8 +249,8 @@ eval select $mysql_errno as "after_failing_deallocate" ; # ---------------------------------------------------------------------------- # test cases for "--disable_abort_on_error" # -# "--disable_abort_on_error" switches the abort of mysqltest -# after "unmasked" failing statements off. +# "--disable_abort_on_error" switches off the abort of mysqltest +# after "unmasked" failing statements. # # The default is "--enable_abort_on_error". # @@ -257,13 +258,13 @@ eval select $mysql_errno as "after_failing_deallocate" ; # --error and --error # in the line before the failing statement. # -# There are some additional test case for $mysql_errno +# There are some additional test cases for $mysql_errno # because "--disable_abort_on_error" enables a new situation. # Example: "unmasked" statement fails + analysis of $mysql_errno # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Switch the abort on error off and check the effect on $mysql_errno +# Switch off the abort on error and check the effect on $mysql_errno # ---------------------------------------------------------------------------- --error 1064 garbage ; @@ -316,7 +317,6 @@ select 3 from t1 ; # #select 3 from t1 ; -# End of 4.1 tests --error 1 --exec echo "disable_abort_on_error; enable_abort_on_error; error 1064; select 3 from t1; select 3 from t1;" | $MYSQL_TEST 2>&1 @@ -344,7 +344,7 @@ select 3 from t1 ; # ---------------------------------------------------------------------------- # Test detect end of line "junk" -# Most likely causes by a missing delimiter +# Most likely caused by a missing delimiter # ---------------------------------------------------------------------------- # Too many parameters to function @@ -359,23 +359,95 @@ select 3 from t1 ; # Missing delimiter # The comment will be "sucked into" the sleep command since # delimiter is missing until after "show status" ---system echo "sleep 4" > var/log/mysqltest.sql ---system echo "# A comment" >> var/log/mysqltest.sql ---system echo "show status;" >> var/log/mysqltest.sql +--system echo "sleep 4" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "# A comment" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "show status;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql --error 1 ---exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 + +# +# Missing delimiter until eof +# The comment will be "sucked into" the sleep command since +# delimiter is missing +--system echo "sleep 7" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "# Another comment" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 # # Extra delimiter # --error 1 --exec echo "--sleep 4;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--disable_query_log;" | $MYSQL_TEST 2>&1 # Allow trailing # comment --sleep 1 # Wait for insert delayed to be executed. --sleep 1 # Wait for insert delayed to be executed. +# ---------------------------------------------------------------------------- +# Test error +# ---------------------------------------------------------------------------- + +# Missing argument +--error 1 +--exec echo "error;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--error" | $MYSQL_TEST 2>&1 + +# First char must be uppercase 'S' or 'E' or [0-9] +--error 1 +--exec echo "--error s99999" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--error e99999" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--error 9eeeee" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--error 1sssss" | $MYSQL_TEST 2>&1 + +# First char 'S' but too long +--error 1 +--exec echo "--error S999999" | $MYSQL_TEST 2>&1 + +# First char 'S' but lowercase char found +--error 1 +--exec echo "--error S99a99" | $MYSQL_TEST 2>&1 + +# First char 'S' but too short +--error 1 +--exec echo "--error S9999" | $MYSQL_TEST 2>&1 + +# First char 'E' but not found in error array +--error 1 +--exec echo "--error E9999" | $MYSQL_TEST 2>&1 + +# First char [0-9] but contains chars +--error 1 +--exec echo "--error 999e9" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--error 9b" | $MYSQL_TEST 2>&1 + +# Multiple errorcodes separated by ',' +--error 1,1,1,1 +#--error 9,ER_PARSE_ERROR +#--error ER_PARSE_ERROR +#--error 9,ER_PARSE_ERROR,9,ER_PARSE_ERROR +#--error 9, ER_PARSE_ERROR, 9, ER_PARSE_ERROR +#--error 9,S00000,9,ER_PARSE_ERROR +#--error 9,S00000,9,ER_PARSE_ERROR,ER_PARSE_ERROR,ER_PARSE_ERROR,9,10,11,12 +--error 9,S00000,9 +--error 9,S00000,9,9,10,11,12 +--error 9 ,10 +--error 9 , 10 +--error 9 , 10 +--error 9 , 10 + +# Too many errorcodes specified +--error 1 +--exec echo "--error 1,2,3,4,5,6,7,8,9,10,11" | $MYSQL_TEST 2>&1 + # ---------------------------------------------------------------------------- # Test echo command @@ -399,8 +471,8 @@ echo - MySQL: The world''s - source database; echo - MySQL: The world''s --- most popular open --- source database; +-- most popular +-- open source database; echo # MySQL: The --world''s @@ -419,7 +491,7 @@ echo ; # Illegal use of echo --error 1 ---exec echo "echo $;" | $MYSQL_TEST 2>&1 +--exec echo "echo \$;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- @@ -457,8 +529,8 @@ echo $message; let $message= -- MySQL: The -- world''s most --- popular open --- source database; +-- popular +-- open source database; echo $message; let $message= # MySQL: The @@ -495,9 +567,21 @@ echo $where2; let $where3=a long $where variable content; echo $where3; +let $where3=a long \\\$where variable content; +echo $where3; + let $novar1= $novar2; echo $novar1; +let $cat=na; +let $cat=ba$cat$cat; +echo banana = $cat; + +# ba\$cat\$cat should have been sufficient. +# ba\\\$cat\\\$cat -> ba\$cat\$cat -> ba$cat$cat -> banana +# Magnus' upcoming patch will fix the missing second interpretation. +let $cat=ba\\\$cat\\\$cat; +echo Not a banana: $cat; # Test illegal uses of let @@ -506,22 +590,19 @@ echo $novar1; --exec echo "let ;" | $MYSQL_TEST 2>&1 --error 1 ---exec echo "let $=hi;" | $MYSQL_TEST 2>&1 +--exec echo "let \$=hi;" | $MYSQL_TEST 2>&1 --error 1 ---exec echo "let hi=hi;" | $MYSQL_TEST 2>&1 +--exec echo "let \$1 hi;" | $MYSQL_TEST 2>&1 --error 1 ---exec echo "let $1 hi;" | $MYSQL_TEST 2>&1 +--exec echo "let \$m hi;" | $MYSQL_TEST 2>&1 --error 1 ---exec echo "let $m hi;" | $MYSQL_TEST 2>&1 +--exec echo "let \$hi;" | $MYSQL_TEST 2>&1 --error 1 ---exec echo "let $hi;" | $MYSQL_TEST 2>&1 - ---error 1 ---exec echo "let $ hi;" | $MYSQL_TEST 2>&1 +--exec echo "let \$ hi;" | $MYSQL_TEST 2>&1 --error 1 --exec echo "let =hi;" | $MYSQL_TEST 2>&1 @@ -529,6 +610,55 @@ echo $novar1; --error 1 --exec echo "let hi;" | $MYSQL_TEST 2>&1 +# More advanced test for bug#17280 +let $success= 1; +--echo # Execute: --echo # success: \$success +--echo # success: $success +--echo # Execute: echo # success: \$success ; +echo # success: $success ; + +--echo # The next two variants work fine and expand the content of \$success +--echo # Execute: --echo \$success +--echo $success +--echo # Execute: echo \$success ; +echo $success ; + +# ---------------------------------------------------------------------------- +# Test to assign let from query +# let $=``; +# ---------------------------------------------------------------------------- +--disable_parsing +echo var1; +let $var1= `select "hi" as "Col", 1 as "Column1", "hi there" as Col3`; +echo $var1; +echo $var1_Col; +echo $var1_Column1; +echo $var1_Col3; + +echo var2; +let $var2= `select 2 as "Column num 2"`; +echo $var2; +echo $var2_Column num 2; +echo $var2_Column; + +echo var2 again; +let $var2= `select 2 as "Column num 2"`; +echo $var2; +echo $var2_Column num 2; +echo $var2_Column_num_2; +echo $var2_Column; + +echo var3 two columns with same name; +let $var3= `select 1 as "Col", 2 as "Col", 3 as "var3"`; +echo $var3; +echo $var3_Col; +echo $var3_Col; +echo $var3_var3; + +#echo failing query in let; +#--error 1 +#--exec echo "let $var2= `failing query;`" | $MYSQL_TEST 2>&1 +--enable_parsing # ---------------------------------------------------------------------------- # Test source command # ---------------------------------------------------------------------------- @@ -538,29 +668,36 @@ echo $novar1; --error 1 --exec echo "source ;" | $MYSQL_TEST 2>&1 +# Fix win paths +--replace_result \\ / +# Source a nonexisting file --error 1 --exec echo "source non_existingFile;" | $MYSQL_TEST 2>&1 # Too many source ---exec echo "source var/tmp/recursive.sql;" > var/tmp/recursive.sql +--exec echo "source $MYSQLTEST_VARDIR/tmp/recursive.sql;" > $MYSQLTEST_VARDIR/tmp/recursive.sql +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1 ---exec echo "source var/tmp/recursive.sql;" | $MYSQL_TEST 2>&1 +--exec echo "source $MYSQLTEST_VARDIR/tmp/recursive.sql;" | $MYSQL_TEST 2>&1 # Source a file with error ---exec echo "garbage ;" > var/tmp/error.sql +--exec echo "garbage ;" > $MYSQLTEST_VARDIR/tmp/error.sql +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1 ---exec echo "source var/tmp/error.sql;" | $MYSQL_TEST 2>&1 +--exec echo "source $MYSQLTEST_VARDIR/tmp/error.sql;" | $MYSQL_TEST 2>&1 # Test execution of source in a while loop ---exec echo "echo here is the sourced script;" > var/tmp/sourced.sql +--write_file $MYSQLTEST_VARDIR/tmp/sourced.inc +echo here is the sourced script; +EOF --disable_query_log let $outer= 2; # Number of outer loops while ($outer) { eval SELECT '$outer = outer loop variable after while' AS ""; - --source var/tmp/sourced.sql + --source $MYSQLTEST_VARDIR/tmp/sourced.inc eval SELECT '$outer = outer loop variable before dec' AS ""; dec $outer; @@ -581,7 +718,6 @@ while ($outer) # Test execution of source in a while loop ---exec echo "--source var/tmp/sourced.sql" > var/tmp/sourced1.sql --disable_abort_on_error # Sourcing of a file within while loop, sourced file will # source other file @@ -589,11 +725,12 @@ let $num= 9; while ($num) { SELECT 'In loop' AS ""; - --source var/tmp/sourced1.sql + --source $MYSQLTEST_VARDIR/tmp/sourced.inc dec $num; } --enable_abort_on_error --enable_query_log +--remove_file $MYSQLTEST_VARDIR/tmp/sourced.inc # ---------------------------------------------------------------------------- # Test sleep command @@ -683,7 +820,7 @@ system echo "hej" > /dev/null; --exec echo "system false;" | $MYSQL_TEST 2>&1 --disable_abort_on_error -system NonExistsinfComamdn; +system NonExistsinfComamdn 2> /dev/null; --enable_abort_on_error @@ -700,6 +837,30 @@ echo test3stop --delimiter ; echo test4; + +# ---------------------------------------------------------------------------- +# Test if +# ---------------------------------------------------------------------------- + +let $counter=10; +if ($counter) +{ + echo Counter is greater than 0, (counter=10); +} +if (!$counter) +{ + echo Counter is not 0, (counter=10); +} +let $counter=0; +if ($counter) +{ + echo Counter is greater than 0, (counter=0); +} +if (!$counter) +{ + echo Counter is not 0, (counter=0); +} + # ---------------------------------------------------------------------------- # Test while, { and } # ---------------------------------------------------------------------------- @@ -713,11 +874,158 @@ while ($i) # One liner #let $i=1;while ($i){echo $i;dec $i;} - +let $i=0; +while (!$i) +{ + echo Testing while with not; + inc $i; +} # Exceed max nesting level +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest_while.inc +let $1 = 10; +while ($1) +{ +while ($1) +{ +while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + echo $1; + dec $1; +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +EOF +# Fix win path +--replace_result \\ / $MYSQLTEST_VARDIR MYSQLTEST_VARDIR --error 1 ---exec echo "source include/mysqltest_while.inc;" | $MYSQL_TEST 2>&1 +--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest_while.inc;" | $MYSQL_TEST 2>&1 +--remove_file $MYSQLTEST_VARDIR/tmp/mysqltest_while.inc --error 1 --exec echo "while \$i;" | $MYSQL_TEST 2>&1 --error 1 @@ -731,20 +1039,20 @@ while ($i) --error 1 --exec echo "{;" | $MYSQL_TEST 2>&1 ---system echo "while (0)" > var/log/mysqltest.sql ---system echo "echo hej;" >> var/log/mysqltest.sql +--system echo "while (0)" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "echo hej;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql --error 1 ---exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 ---system echo "while (0)" > var/log/mysqltest.sql ---system echo "{echo hej;" >> var/log/mysqltest.sql +--system echo "while (0)" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "{echo hej;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql --error 1 ---exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 ---system echo "while (0){" > var/log/mysqltest.sql ---system echo "echo hej;" >> var/log/mysqltest.sql +--system echo "while (0){" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "echo hej;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql --error 1 ---exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 # ---------------------------------------------------------------------------- # Test error messages returned from comments starting with a command @@ -772,7 +1080,7 @@ select "a" as col1, "c" as col2; --exec echo "replace_result a;" | $MYSQL_TEST 2>&1 --error 1 --exec echo "replace_result a ;" | $MYSQL_TEST 2>&1 ---exec echo "replace_result a b;" | $MYSQL_TEST 2>&1 +--exec echo "replace_result a b; echo OK;" | $MYSQL_TEST 2>&1 --error 1 --exec echo "--replace_result a b c" | $MYSQL_TEST 2>&1 --error 1 @@ -809,6 +1117,71 @@ select "a" as col1, "c" as col2; --error 1 --exec echo "save_master_pos; sync_with_master a;" | $MYSQL_TEST 2>&1 +# ---------------------------------------------------------------------------- +# Test connect +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "connect;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "connect ();" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "connect (con2);" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "connect (con2,);" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "connect (con2,localhost,root,,illegal_db);" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "connect (con1,localhost,root,,,illegal_port,);" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "connect (con1,localhost,root,,,,,SMTP POP);" | $MYSQL_TEST 2>&1 + +# Repeat connect/disconnect +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +let $i=100; +while ($i) +{ + connect (test_con1,localhost,root,,); + disconnect test_con1; + dec $i; +} +EOF +--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK;" | $MYSQL_TEST 2>&1 + +# Repeat connect/disconnect, exceed max number of connections +--system echo "let \$i=200;" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "while (\$i)" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "{" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo " connect (test_con1,localhost,root,,); " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo " disconnect test_con1; " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo " dec \$i; " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "}" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--error 1 +--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1 + +# Select disconnected connection +--system echo "connect (test_con1,localhost,root,,);" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "disconnect test_con1; " >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "connection test_con1;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--error 1 +--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1 + +# Connection name already used +--system echo "connect (test_con1,localhost,root,,);" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--system echo "connect (test_con1,localhost,root,,);" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--error 1 +--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql;" | $MYSQL_TEST 2>&1 + +# connect when "disable_abort_on_error" caused "connection not found" +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +--disable_abort_on_error +connect (con1,localhost,root,,); +connection default; +connection con1; +--enable_abort_on_error # ---------------------------------------------------------------------------- # Test mysqltest arguments @@ -818,6 +1191,8 @@ select "a" as col1, "c" as col2; --exec $MYSQL_TEST < $MYSQL_TEST_DIR/include/mysqltest-x.inc --exec $MYSQL_TEST -x $MYSQL_TEST_DIR/include/mysqltest-x.inc --exec $MYSQL_TEST --test_file=$MYSQL_TEST_DIR/include/mysqltest-x.inc +# Fix Win paths +--replace_result \\ / --error 1 --exec $MYSQL_TEST -x non_existing_file.inc 2>&1 @@ -841,3 +1216,275 @@ while ($num) SELECT 1 as a; + +# +# Bug #10251: Identifiers containing quotes not handled correctly +# +select 1 as `a'b`, 2 as `a"b`; + +# Test escaping of quotes +select 'aaa\\','aa''a',"aa""a"; + +# +# Check of include/show_msg.inc and include/show_msg80.inc +# + +# The message contains in most cases a string with the default character set +let $message= Here comes a message; +--source include/show_msg.inc + +# The message could also contain a string with character set utf8 +let $message= `SELECT USER()`; +--source include/show_msg.inc + +# The message contains more then 80 characters on multiple lines +# and is kept between double quotes. +let $message= +"Here comes a very very long message that + - is longer then 80 characters and + - consists of several lines"; +--source include/show_msg80.inc + +# The message contains more then 80 characters on multiple lines +# and uses the auxiliary character "." at the beginning of the message lines. +let $message= . Here comes a very very long message that + . - is longer then 80 characters and + . - consists of several lines; +--source include/show_msg80.inc + +# +# Test --enable_parsing / disable_parsing +# +--disable_query_log +--disable_parsing +# The following will not enable query logging +--enable_query_log +select "this will not be executed"; +--enable_parsing +select "this will be executed"; +--enable_query_log + +# +# Test zero length result file. Should not pass +# +--exec touch $MYSQLTEST_VARDIR/tmp/zero_length_file.result +--exec echo "echo ok;" > $MYSQLTEST_VARDIR/tmp/query.sql +--error 1 +--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/zero_length_file.result 2>&1 +# +# Test that a test file that does not generate any output fails. +# +--exec echo "let \$i= 1;" > $MYSQLTEST_VARDIR/tmp/query.sql +--error 1 +--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql 2>&1 + +# +# Test that mysqltest fails when there are no queries executed +# but a result file exists +# NOTE! This will never happen as long as it's not allowed to have +# test files that produce no output +#--exec echo "something" > $MYSQLTEST_VARDIR/tmp/result_file.result +#--exec echo "let \$i= 1;" > $MYSQLTEST_VARDIR/tmp/query.sql +#--error 1 +#--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/query.sql -R $MYSQLTEST_VARDIR/tmp/result_file.result 2>&1 + +# +# Bug #11731 mysqltest in multi-statement queries ignores errors in +# non-1st queries +# + +echo Failing multi statement query; +# PS does not support multi statement +--exec echo "--disable_ps_protocol" > $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "delimiter ||||;" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "create table t1 (a int primary key);" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "insert into t1 values (1);" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "select 'select-me';" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "insertz 'error query'||||" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "delimiter ;||||" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql + +--error 1 +--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/bug11731.sql 2>&1 +drop table t1; + +--error 1 +--exec $MYSQL_TEST --record -x $MYSQLTEST_VARDIR/tmp/bug11731.sql -R $MYSQLTEST_VARDIR/tmp/bug11731.out 2>&1 +# The .out file should be non existent +--exec test ! -s $MYSQLTEST_VARDIR/tmp/bug11731.out +drop table t1; + + +echo Multi statement using expected error; +# PS does not support multi statement +--exec echo "--disable_ps_protocol" > $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "delimiter ||||;" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "--error 1064" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "create table t1 (a int primary key);" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "insert into t1 values (1);" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "select 'select-me';" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "insertz "error query"||||" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql +--exec echo "delimiter ;||||" >> $MYSQLTEST_VARDIR/tmp/bug11731.sql + +# These two should work since the error is expected +--exec $MYSQL_TEST -x $MYSQLTEST_VARDIR/tmp/bug11731.sql 2>&1 +drop table t1; + +--exec $MYSQL_TEST --record -x $MYSQLTEST_VARDIR/tmp/bug11731.sql -R $MYSQLTEST_VARDIR/tmp/bug11731.out 2>&1 +# The .out file should exist +--exec test -s $MYSQLTEST_VARDIR/tmp/bug11731.out +drop table t1; + +# +# Bug#19890 mysqltest: "query" command is broken +# + +# It should be possible to use the command "query" to force mysqltest to +# send the command to the server although it's a builtin mysqltest command. +--error 1064 +query sleep; + +--error 1064 +--query sleep + +# Just an empty query command +--error 1065 +query ; + +# test for replace_regex +--replace_regex /at/b/ +select "at" as col1, "c" as col2; + +--replace_regex /at/b/i +select "at" as col1, "AT" as col2, "c" as col3; + +--replace_regex /a/b/ /ct/d/ +select "a" as col1, "ct" as col2; + +--replace_regex /(strawberry)/raspberry and \1/ /blueberry/blackberry/ /potato/tomato/; +select "strawberry","blueberry","potato"; + +--error 1 +--exec echo "--replace_regex a" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--replace_regex a;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_regex a;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_regex a ;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_regex a b; echo OK;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--replace_regex /a b c" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_regex /a /b c ;" | $MYSQL_TEST 2>&1 + +# REQUIREMENT +# replace_regex should replace substitutions from left to right in output + +create table t1 (a int, b int); +insert into t1 values (1,3); +insert into t1 values (2,4); +--replace_regex /A/C/ /B/D/i /3/2/ /2/1/ +select * from t1; +drop table t1; + +# ---------------------------------------------------------------------------- +# test for remove_file +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "remove_file ;" | $MYSQL_TEST 2>&1 + +--error 1 +remove_file non_existing_file; + +# ---------------------------------------------------------------------------- +# test for write_file +# ---------------------------------------------------------------------------- +--error 1 +--exec echo "write_file ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "write_file filename ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "write_file filename \";" | $MYSQL_TEST 2>&1 + +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +Content for test_file1 +EOF +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp END_DELIMITER; +Content for test_file1 contains EOF +END_DELIMITER +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + +# ---------------------------------------------------------------------------- +# test for file_exist +# ---------------------------------------------------------------------------- +--error 1 +--exec echo "file_exists ;" | $MYSQL_TEST 2>&1 + +--error 0,1 +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +--error 1 +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +write_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +Content for test_file1 +EOF +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/test_file1.tmp; +--error 1 +file_exists $MYSQLTEST_VARDIR/tmp/test_file1.tmp; + + +# ---------------------------------------------------------------------------- +# test for copy_file +# ---------------------------------------------------------------------------- +--write_file $MYSQLTEST_VARDIR/tmp/file1.tmp +file1 +EOF + +copy_file $MYSQLTEST_VARDIR/tmp/file1.tmp $MYSQLTEST_VARDIR/tmp/file2.tmp; +file_exists $MYSQLTEST_VARDIR/tmp/file2.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/file1.tmp; +remove_file $MYSQLTEST_VARDIR/tmp/file2.tmp; + +--error 1 +--exec echo "copy_file ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "copy_file from_file;" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# test for perl +# ---------------------------------------------------------------------------- +--perl +print "hello\n"; +EOF + +--perl EOF +print "hello\n"; +EOF + +--perl DELIMITER +print "hello\n"; +DELIMITER + +--error 1 +--exec echo "perl TOO_LONG_DELIMITER ;" | $MYSQL_TEST 2>&1 + +perl; +print "hello\n"; +EOF + +perl; + # Print "hello" + print "hello\n"; +EOF + + +--echo End of tests diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 0ca293eb1ba..5be56c59049 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -351,14 +351,14 @@ create table t1 (a int, b int); insert into t1 (a, b) values (1,1), (1,2), (2,1), (2,2); prepare stmt from "explain select * from t1 where t1.a=2 and t1.a=t1.b and t1.b > 1 + ?"; ---replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - set @v=5; -execute stmt using @v; --replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - +execute stmt using @v; set @v=0; -execute stmt using @v; --replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - +execute stmt using @v; set @v=5; +--replace_column 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - execute stmt using @v; drop table t1; deallocate prepare stmt; diff --git a/mysql-test/t/ps_1general.test b/mysql-test/t/ps_1general.test index 6f15ba8f673..ec4964d116a 100644 --- a/mysql-test/t/ps_1general.test +++ b/mysql-test/t/ps_1general.test @@ -305,8 +305,8 @@ prepare stmt4 from ' show table status from test like ''t9%'' '; --replace_result 2147483647 4294967295 # Bug#4288 execute stmt4; ---replace_column 2 # prepare stmt4 from ' show status like ''Threads_running'' '; +--replace_column 2 # execute stmt4; prepare stmt4 from ' show variables like ''sql_mode'' '; execute stmt4; diff --git a/mysql-test/t/ps_grant.test b/mysql-test/t/ps_grant.test index 4cb056db358..afd543caacc 100644 --- a/mysql-test/t/ps_grant.test +++ b/mysql-test/t/ps_grant.test @@ -35,7 +35,7 @@ use mysqltest; --source include/ps_create.inc --source include/ps_renew.inc --enable_query_log -eval use $DB; +use test; grant usage on mysqltest.* to second_user@localhost identified by 'looser' ; grant select on mysqltest.t9 to second_user@localhost diff --git a/mysql-test/t/rpl000018.test b/mysql-test/t/rpl000018.test deleted file mode 100644 index aee052ffd28..00000000000 --- a/mysql-test/t/rpl000018.test +++ /dev/null @@ -1,29 +0,0 @@ -# -# Running test with abort-slave-event-count=1 -# This will force slave to reconnect after every event -# - -require_manager; -connect (master,localhost,root,,test,0,master.sock); -connect (slave,localhost,root,,test,0,slave.sock); -connection master; -reset master; -server_stop master; -server_start master; -connection slave; -reset slave; -start slave; -connection master; -show binary logs; ---disable_warnings -drop table if exists t1; ---enable_warnings -create table t1(n int); -insert into t1 values (3351); -sync_slave_with_master; -select * from t1; -connection master; -drop table t1; -sync_slave_with_master; - -# End of 4.1 tests diff --git a/mysql-test/t/rpl_chain_temp_table.test b/mysql-test/t/rpl_chain_temp_table.test deleted file mode 100644 index 96e228a17a1..00000000000 --- a/mysql-test/t/rpl_chain_temp_table.test +++ /dev/null @@ -1,101 +0,0 @@ - # This test makes some assumptions about values of thread ids, which should be -# true if the servers have been restarted for this test. So we want to -# stop/restart servers. Note that if assumptions are wrong, the test will not -# fail; it will just fail to test the error-prone scenario. -# Using the manager is the only way to have more than one slave server. -# So you must run this test with --manager. - -require_manager; -server_stop master; -server_start master; -server_stop slave; -server_start slave; -# no need for slave_sec (no assumptions on thread ids for this server). - -source include/master-slave.inc; -connect (slave_sec,localhost,root,,test,0,slave.sock-1); -connection master; -save_master_pos; -connection slave; -sync_with_master; -reset master; -save_master_pos; -connection slave_sec; -eval change master to master_host='127.0.0.1',master_port=$SLAVE_MYPORT, master_user='root'; -start slave; -sync_with_master; - -# :P now we have a chain ready-to-test. - -connection master; -create temporary table t1 (a int); -save_master_pos; -connection slave; -sync_with_master; -connection master1; -create temporary table t1 (a int); -save_master_pos; -connection slave; -sync_with_master; -save_master_pos; - -# First test: - -connection slave_sec; -# Before BUG#1686 ("If 2 master threads with same-name temp table, slave makes -# bad binlog") was fixed, sync_with_master failed -sync_with_master; -show status like 'slave_open_temp_tables'; - -# 'master' and 'master1' usually have thread id 2-3 or 3-4. -# 'slave' and 'slave1' usually have thread id 2-3. -connection slave; -create temporary table t1 (a int); -connection slave1; -create temporary table t1 (a int); -# So it's likely that in the binlog of slave we get -# server_id=of_master thread_id=3 create temp... -# server_id=of_slave thread_id=3 create temp... -# which would confuse slave-sec unless slave-sec uses server id to distinguish -# between temp tables (here thread id is obviously not enough to distinguish). - -save_master_pos; - -# Second test: - -connection slave_sec; -# If we did not use the server id to distinguish between temp tables, -# sync_with_master would fail -sync_with_master; -show status like 'slave_open_temp_tables'; - -# Third test (BUG#1240 "slave of slave breaks when STOP SLAVE was issud on -# parent slave and temp tables"). -stop slave; -connection slave; -insert into t1 values(1); -create table t2 as select * from t1; -save_master_pos; -connection slave_sec; -start slave; -sync_with_master; -show status like 'slave_open_temp_tables'; -select * from t2; - -# clean up -connection slave; -drop table t2; -save_master_pos; -connection slave_sec; -sync_with_master; - -# On purpose, we don't delete the temporary tables explicitely. -# So temp tables remain on slave (remember they are not deleted when the slave -# SQL thread terminates). If you run this test with -# --valgrind --valgrind-options=--show-reachable=yes -# you will see if they get cleaned up at slave's shutdown (that is, if the -# memory they use is freed (it should) by mysqld before it terminates). -# If they wouldn't be cleaned up, you would see some "still reachable" blocks in -# Valgrind. - -# End of 4.1 tests diff --git a/mysql-test/t/rpl_failsafe.test b/mysql-test/t/rpl_failsafe.test deleted file mode 100644 index 4336d897fc0..00000000000 --- a/mysql-test/t/rpl_failsafe.test +++ /dev/null @@ -1,24 +0,0 @@ -require_manager; -source include/master-slave.inc; -connect (slave_sec,localhost,root,,test,0,slave.sock-1); -connect (slave_ter,localhost,root,,test,0,slave.sock-2); -connection master; -show variables like 'rpl_recovery_rank'; -show status like 'Rpl_status'; -create table t1(n int); -drop table t1; -sync_slave_with_master; -show variables like 'rpl_recovery_rank'; -show status like 'Rpl_status'; -connection slave_sec; -start slave; -sync_with_master; -show variables like 'rpl_recovery_rank'; -show status like 'Rpl_status'; -connection slave_ter; -start slave; -sync_with_master; -show variables like 'rpl_recovery_rank'; -show status like 'Rpl_status'; - -# End of 4.1 tests diff --git a/mysql-test/t/rpl_flush_tables.test b/mysql-test/t/rpl_flush_tables.test index 378fa479f09..aea8d7a5353 100644 --- a/mysql-test/t/rpl_flush_tables.test +++ b/mysql-test/t/rpl_flush_tables.test @@ -8,6 +8,8 @@ # merge table getting renamed. --source include/not_windows.inc +let $SERVER_VERSION=`select version()`; + create table t1 (a int); insert into t1 values (10); create table t2 (a int); diff --git a/mysql-test/t/rpl_heap.test b/mysql-test/t/rpl_heap.test deleted file mode 100644 index 66dac1d7926..00000000000 --- a/mysql-test/t/rpl_heap.test +++ /dev/null @@ -1,51 +0,0 @@ -# You must run this test with --manager. - -require_manager; - -# Don't know why, but using TCP/IP connections makes this test fail -# with "Lost connection to MySQL server during query" when we -# issue a query after the server restart. -# Maybe this is something awkward in mysqltest or in the manager? -# So we use sockets. -connect (master,localhost,root,,test,0,master.sock); -connect (slave,localhost,root,,test,0,slave.sock); - -connection master; -reset master; -drop table if exists t1; -# we use CREATE SELECT to verify that DELETE does not get into binlog -# before CREATE SELECT -create table t1 type=HEAP select 10 as a; -insert into t1 values(11); -save_master_pos; -show binlog events from 79; -connection slave; -reset slave; -start slave; -sync_with_master; -show create table t1; -select * from t1; # should be one row - -server_stop master; -server_start master; - -connection master; -select * from t1; -# to check that DELETE is not written twice -# (the LIMIT is to not use the query cache) -select * from t1 limit 10; -save_master_pos; -show binlog events in 'master-bin.002' from 79; - -connection slave; -sync_with_master; -select * from t1; # should be empty - -# clean up -connection master; -drop table t1; -save_master_pos; -connection slave; -sync_with_master; - -# End of 4.1 tests diff --git a/mysql-test/t/rpl_trunc_temp.test b/mysql-test/t/rpl_trunc_temp.test index be570a6f80c..b4ea3c318da 100644 --- a/mysql-test/t/rpl_trunc_temp.test +++ b/mysql-test/t/rpl_trunc_temp.test @@ -29,7 +29,4 @@ connection slave; show status like 'Slave_open_temp_tables'; -connection master; - - # End of 4.1 tests diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 10dfb788c10..d34da8eabe2 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -1721,7 +1721,7 @@ select (select a from t1) = (1,2); select (1,2,3) = (select * from t1); -- error 1241 select (select * from t1) = (1,2,3); -drop table t1 +drop table t1; # # Item_int_with_ref check (BUG#10020) diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 2ac55da7442..2c3f4e5efce 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -23,7 +23,7 @@ CREATE TABLE t2 (a char(257), b varbinary(70000), c varchar(70000000)); show columns from t2; create table t3 (a long, b long byte); show create TABLE t3; -drop table t1,t2,t3 +drop table t1,t2,t3; # # Check errors with blob From 503c0e1c081ed743d4e19e2311a72781191f554d Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 15:48:41 +0200 Subject: [PATCH 028/235] Add two new result files mysql-test/r/init_file.result: Add new file init_file.result mysql-test/r/mysql_client_test.result: Add new file mysql_client_test.result --- mysql-test/r/init_file.result | 2 ++ mysql-test/r/mysql_client_test.result | 1 + 2 files changed, 3 insertions(+) create mode 100644 mysql-test/r/init_file.result create mode 100644 mysql-test/r/mysql_client_test.result diff --git a/mysql-test/r/init_file.result b/mysql-test/r/init_file.result new file mode 100644 index 00000000000..5404a7b2064 --- /dev/null +++ b/mysql-test/r/init_file.result @@ -0,0 +1,2 @@ +ok +End of 4.1 tests diff --git a/mysql-test/r/mysql_client_test.result b/mysql-test/r/mysql_client_test.result new file mode 100644 index 00000000000..9766475a418 --- /dev/null +++ b/mysql-test/r/mysql_client_test.result @@ -0,0 +1 @@ +ok From d1e63094713f4b21a2c6885b70bae637bd4cf90a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 15:59:56 +0200 Subject: [PATCH 029/235] Delete files now moved into mysqltest.test BitKeeper/deleted/.del-sourced.inc: Delete: mysql-test/include/sourced.inc BitKeeper/deleted/.del-mysqltest_while.inc: Delete: mysql-test/include/mysqltest_while.inc BitKeeper/deleted/.del-sourced1.inc: Delete: mysql-test/include/sourced1.inc --- mysql-test/include/mysqltest_while.inc | 137 ------------------------- mysql-test/include/sourced.inc | 1 - mysql-test/include/sourced1.inc | 1 - 3 files changed, 139 deletions(-) delete mode 100644 mysql-test/include/mysqltest_while.inc delete mode 100644 mysql-test/include/sourced.inc delete mode 100644 mysql-test/include/sourced1.inc diff --git a/mysql-test/include/mysqltest_while.inc b/mysql-test/include/mysqltest_while.inc deleted file mode 100644 index 90b05ee2695..00000000000 --- a/mysql-test/include/mysqltest_while.inc +++ /dev/null @@ -1,137 +0,0 @@ -let $1 = 10; -while ($1) -{ -while ($1) -{ -while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - while ($1) -{ - echo $1; - dec $1; -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} -} diff --git a/mysql-test/include/sourced.inc b/mysql-test/include/sourced.inc deleted file mode 100644 index be1a270641a..00000000000 --- a/mysql-test/include/sourced.inc +++ /dev/null @@ -1 +0,0 @@ -echo here is the sourced script; diff --git a/mysql-test/include/sourced1.inc b/mysql-test/include/sourced1.inc deleted file mode 100644 index 920561e5de2..00000000000 --- a/mysql-test/include/sourced1.inc +++ /dev/null @@ -1 +0,0 @@ ---source include/sourced.inc From 807b9f94372208931802a5b836fa75aac5b82286 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 16:34:44 +0200 Subject: [PATCH 030/235] Fix typo - Change con_host to ds_connection_name.str client/mysqltest.c: Change con_host to ds_connection_name.str --- client/mysqltest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 623c33d0f4f..d057e7ea4f0 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3025,7 +3025,7 @@ void do_connect(struct st_command *command) opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ - opt_ssl_verify_server_cert= !strcmp(con_host, "localhost"); + opt_ssl_verify_server_cert= !strcmp(ds_connection_name.str, "localhost"); mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif From 52da19517ca91e219641684626ba58b227818db4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 16:35:46 +0200 Subject: [PATCH 031/235] Add mysys/my_copy.c as sources for mysqltest --- client/Makefile.am | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/client/Makefile.am b/client/Makefile.am index d3c320db56c..29624f2017f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -38,7 +38,9 @@ noinst_HEADERS = sql_string.h completion_hash.h my_readline.h \ mysql_SOURCES = mysql.cc readline.cc sql_string.cc completion_hash.cc mysqladmin_SOURCES = mysqladmin.cc mysql_LDADD = @readline_link@ @TERMCAP_LIB@ $(LDADD) $(CXXLDFLAGS) -mysqltest_SOURCES= mysqltest.c $(top_srcdir)/mysys/my_getsystime.c \ +mysqltest_SOURCES= mysqltest.c \ + $(top_srcdir)/mysys/my_getsystime.c \ + $(top_srcdir)/mysys/my_copy.c \ $(yassl_dummy_link_fix) mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD) mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c $(top_srcdir)/mysys/my_new.cc From 78f47b1b1080833241860c6213854fe04487ff12 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 11:26:50 -0400 Subject: [PATCH 032/235] Bug#19660 mysqldump --single-transaction should be with CONSISTENT SNAPSHOT client/mysqldump.c: Bug#19660 mysqldump --single-transaction should be with CONSISTENT SNAPSHOT - Remove old BEGIN syntax and replace with START TRANSATION. Add CONSISTENT SNAPSHOT option for servers that support it. --- client/mysqldump.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 3445a23eb5e..c55e4157394 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2407,7 +2407,7 @@ static int do_reset_master(MYSQL *mysql_con) } -static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now) +static int start_transaction(MYSQL *mysql_con) { /* We use BEGIN for old servers. --single-transaction --master-data will fail @@ -2422,10 +2422,8 @@ static int start_transaction(MYSQL *mysql_con, my_bool consistent_read_now) "SET SESSION TRANSACTION ISOLATION " "LEVEL REPEATABLE READ") || mysql_query_with_error_report(mysql_con, 0, - consistent_read_now ? "START TRANSACTION " - "WITH CONSISTENT SNAPSHOT" : - "BEGIN")); + "/*!40100 WITH CONSISTENT SNAPSHOT */")); } @@ -2652,7 +2650,7 @@ int main(int argc, char **argv) if ((opt_lock_all_tables || opt_master_data) && do_flush_tables_read_lock(sock)) goto err; - if (opt_single_transaction && start_transaction(sock, test(opt_master_data))) + if (opt_single_transaction && start_transaction(sock)) goto err; if (opt_delete_master_logs && do_reset_master(sock)) goto err; From e6eef5c1a765d27e1a8d1c7d707fb416dfa0ec2f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 13:38:25 -0400 Subject: [PATCH 033/235] Bug #14262: SP: DROP PROCEDURE|VIEW (maybe more) write to binlog too late \ (race cond) It was possible for one thread to interrupt a Data Definition Language statement and thereby get messages to the binlog out of order. Consider: Connection 1: Drop Foo x Connection 2: Create or replace Foo x Connection 2: Log "Create or replace Foo x" Connection 1: Log "Drop Foo x" Local end would have Foo x, but the replicated slaves would not. The fix for this is to wrap all DDL and logging of a kind in the same mutex. Since we already use mutexes for the various parts of altering the server, this only entails moving the logging events down close to the action, inside the mutex protection. BitKeeper/etc/collapsed: BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed --- BitKeeper file /home/cmiller/work/mysql/bug14262/my50-bug14262/BitKeeper/etc/collapsed sql/sp.cc: Move logging inside the routine drop and update functions, so it can be protected by a LOCK_open mutex. (The "create" function already had such a LOCK_open protection.) sql/sql_acl.cc: Move logging inside the grant functions, so that it can be protected by LOCK_grant . sql/sql_db.cc: Add comments that describe how each logging event is protected. sql/sql_parse.cc: Move all logging statements about DDL statements close to the actual event, so each can be protected by the same mutex. sql/sql_table.cc: Widen the scope of the mutex so that logging events are also protected. sql/sql_trigger.cc: Widen the scope of the mutex so that logging events are also protected. sql/sql_view.cc: Pass the head of the table linked-list so we can create a logging statement. Move the logging statement inside the worker function, and notably inside the LOCK_open mutex. Widen the same mutex a little to make room for logging. sql/sql_view.h: Pass the head of the table linked-list so we can create a logging statement. --- BitKeeper/etc/collapsed | 5 ++ sql/sp.cc | 23 ++++++++ sql/sql_acl.cc | 67 ++++++++++++++++++++++- sql/sql_db.cc | 5 ++ sql/sql_parse.cc | 118 +++++++++------------------------------- sql/sql_table.cc | 15 ++--- sql/sql_trigger.cc | 10 ++-- sql/sql_view.cc | 47 ++++++++++++++-- sql/sql_view.h | 2 +- 9 files changed, 183 insertions(+), 109 deletions(-) create mode 100644 BitKeeper/etc/collapsed diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed new file mode 100644 index 00000000000..d831276ffd3 --- /dev/null +++ b/BitKeeper/etc/collapsed @@ -0,0 +1,5 @@ +45143312u0Tz4r0wPXCbUKwdHa2jWA +45143b90ewOQuTW8-jrB3ZSAQvMRJw +45184588w9U72A6KX1hUFeAC4shSHA +45185df8mZbxfp85FbA0VxUXkmDewA +451b110a3ZV6MITl93ehXk2wxrbW7g diff --git a/sql/sp.cc b/sql/sp.cc index a7078da2f50..861ba351160 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -660,6 +660,17 @@ db_drop_routine(THD *thd, int type, sp_name *name) if (table->file->delete_row(table->record[0])) ret= SP_DELETE_ROW_FAILED; } + + if (ret == SP_OK) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -695,6 +706,17 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) if ((table->file->update_row(table->record[1],table->record[0]))) ret= SP_WRITE_ROW_FAILED; } + + if (ret == SP_OK) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + close_thread_tables(thd); DBUG_RETURN(ret); } @@ -773,6 +795,7 @@ print_field_values(THD *thd, TABLE *table, return SP_INTERNAL_ERROR; } } + return SP_OK; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index ae5ea210a47..d54d9910820 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3005,9 +3005,22 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, grant_option=TRUE; thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); + + if (!result) /* success */ + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + rw_unlock(&LOCK_grant); - if (!result) + + if (!result) /* success */ send_ok(thd); + /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -3168,9 +3181,21 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, grant_option=TRUE; thd->mem_root= old_root; pthread_mutex_unlock(&acl_cache->lock); + if (!result && !no_error) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + rw_unlock(&LOCK_grant); + if (!result && !no_error) send_ok(thd); + /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -3276,11 +3301,23 @@ bool mysql_grant(THD *thd, const char *db, List &list, } } VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (!result) + { + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (!result) send_ok(thd); + DBUG_RETURN(result); } @@ -5241,6 +5278,13 @@ bool mysql_create_user(THD *thd, List &list) } VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) @@ -5297,6 +5341,13 @@ bool mysql_drop_user(THD *thd, List &list) rebuild_check_host(); VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) @@ -5366,6 +5417,13 @@ bool mysql_rename_user(THD *thd, List &list) rebuild_check_host(); VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); if (result) @@ -5541,6 +5599,13 @@ bool mysql_revoke_all(THD *thd, List &list) } VOID(pthread_mutex_unlock(&acl_cache->lock)); + + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + rw_unlock(&LOCK_grant); close_thread_tables(thd); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 902539dfdec..05526704eb1 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -542,6 +542,7 @@ bool mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, qinfo.db = db; qinfo.db_len = strlen(db); + /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } send_ok(thd, result); @@ -613,6 +614,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) qinfo.db_len = strlen(db); thd->clear_error(); + /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } send_ok(thd, result); @@ -736,6 +738,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) qinfo.db_len = strlen(db); thd->clear_error(); + /* These DDL methods and logging protected with LOCK_mysql_create_db */ mysql_bin_log.write(&qinfo); } thd->server_status|= SERVER_STATUS_DB_DROPPED; @@ -762,6 +765,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) tbl_name_len= strlen(tbl->table_name) + 3; if (query_pos + tbl_name_len + 1 >= query_end) { + /* These DDL methods and logging protected with LOCK_mysql_create_db */ write_to_binlog(thd, query, query_pos -1 - query, db, db_len); query_pos= query_data_start; } @@ -774,6 +778,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) if (query_pos != query_data_start) { + /* These DDL methods and logging protected with LOCK_mysql_create_db */ write_to_binlog(thd, query, query_pos -1 - query, db, db_len); } } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 28ed3e25d57..bee537a5a19 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3195,6 +3195,7 @@ end_with_restore_list: /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { + /* Presumably, REPAIR and binlog writing doesn't require synchronization */ if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -3229,6 +3230,7 @@ end_with_restore_list: /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { + /* Presumably, ANALYZE and binlog writing doesn't require synchronization */ if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -3254,6 +3256,7 @@ end_with_restore_list: /* ! we write after unlocking the table */ if (!res && !lex->no_write_to_binlog) { + /* Presumably, OPTIMIZE and binlog writing doesn't require synchronization */ if (mysql_bin_log.is_open()) { thd->clear_error(); // No binlog error generated @@ -3542,6 +3545,7 @@ end_with_restore_list: /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */ thd->options|= OPTION_STATUS_NO_TRANS_UPDATE; } + /* DDL and binlog write order protected by LOCK_open */ res= mysql_rm_table(thd, first_table, lex->drop_if_exists, lex->drop_temporary); } @@ -3830,15 +3834,9 @@ end_with_restore_list: break; if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog */ if (!(res= mysql_create_user(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_DROP_USER: @@ -3848,15 +3846,9 @@ end_with_restore_list: break; if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog */ if (!(res= mysql_drop_user(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_RENAME_USER: @@ -3866,15 +3858,9 @@ end_with_restore_list: break; if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog */ if (!(res= mysql_rename_user(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_REVOKE_ALL: @@ -3882,15 +3868,9 @@ end_with_restore_list: if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) && check_global_access(thd,CREATE_USER_ACL)) break; + /* Conditionally writes to binlog */ if (!(res = mysql_revoke_all(thd, lex->users_list))) - { - if (mysql_bin_log.is_open()) - { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); - } break; } case SQLCOM_REVOKE: @@ -3949,6 +3929,7 @@ end_with_restore_list: check_grant_routine(thd, grants | GRANT_ACL, all_tables, lex->type == TYPE_ENUM_PROCEDURE, 0)) goto error; + /* Conditionally writes to binlog */ res= mysql_routine_grant(thd, all_tables, lex->type == TYPE_ENUM_PROCEDURE, lex->users_list, grants, @@ -3961,16 +3942,11 @@ end_with_restore_list: GRANT_ACL), all_tables, 0, UINT_MAX, 0)) goto error; + /* Conditionally writes to binlog */ res= mysql_table_grant(thd, all_tables, lex->users_list, lex->columns, lex->grant, lex->sql_command == SQLCOM_REVOKE); } - if (!res && mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } } else { @@ -3981,16 +3957,11 @@ end_with_restore_list: goto error; } else + /* Conditionally writes to binlog */ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant, lex->sql_command == SQLCOM_REVOKE); if (!res) { - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } if (lex->sql_command == SQLCOM_GRANT) { List_iterator str_list(lex->users_list); @@ -4028,6 +3999,7 @@ end_with_restore_list: We WANT to write and we CAN write. ! we write after unlocking the table. */ + /* Presumably, RESET and binlog writing doesn't require synchronization */ if (!lex->no_write_to_binlog && write_to_binlog) { if (mysql_bin_log.is_open()) @@ -4564,20 +4536,16 @@ end_with_restore_list: already puts on CREATE FUNCTION. */ if (lex->sql_command == SQLCOM_ALTER_PROCEDURE) + /* Conditionally writes to binlog */ result= sp_update_procedure(thd, lex->spname, &lex->sp_chistics); else + /* Conditionally writes to binlog */ result= sp_update_function(thd, lex->spname, &lex->sp_chistics); } } switch (result) { case SP_OK: - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); break; case SP_KEY_NOT_FOUND: @@ -4622,9 +4590,11 @@ end_with_restore_list: } #endif if (lex->sql_command == SQLCOM_DROP_PROCEDURE) - result= sp_drop_procedure(thd, lex->spname); + /* Conditionally writes to binlog */ + result= sp_drop_procedure(thd, lex->spname); /* Conditionally writes to binlog */ else - result= sp_drop_function(thd, lex->spname); + /* Conditionally writes to binlog */ + result= sp_drop_function(thd, lex->spname); /* Conditionally writes to binlog */ } else { @@ -4637,6 +4607,8 @@ end_with_restore_list: { if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0)) goto error; + + /* Does NOT write to binlog */ if (!(res = mysql_drop_function(thd, &lex->spname->m_name))) { send_ok(thd); @@ -4657,12 +4629,6 @@ end_with_restore_list: switch (result) { case SP_OK: - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } send_ok(thd); break; case SP_KEY_NOT_FOUND: @@ -4758,37 +4724,8 @@ end_with_restore_list: { if (end_active_trans(thd)) goto error; - - if (!(res= mysql_create_view(thd, thd->lex->create_view_mode)) && - mysql_bin_log.is_open()) - { - String buff; - const LEX_STRING command[3]= - {{(char *)STRING_WITH_LEN("CREATE ")}, - {(char *)STRING_WITH_LEN("ALTER ")}, - {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}}; - thd->clear_error(); - - buff.append(command[thd->lex->create_view_mode].str, - command[thd->lex->create_view_mode].length); - view_store_options(thd, first_table, &buff); - buff.append(STRING_WITH_LEN("VIEW ")); - /* Test if user supplied a db (ie: we did not use thd->db) */ - if (first_table->db && first_table->db[0] && - (thd->db == NULL || strcmp(first_table->db, thd->db))) - { - append_identifier(thd, &buff, first_table->db, - first_table->db_length); - buff.append('.'); - } - append_identifier(thd, &buff, first_table->table_name, - first_table->table_name_length); - buff.append(STRING_WITH_LEN(" AS ")); - buff.append(first_table->source.str, first_table->source.length); - - Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); - mysql_bin_log.write(&qinfo); - } + /* Conditionally writes to binlog. */ + res= mysql_create_view(thd, first_table, thd->lex->create_view_mode); break; } case SQLCOM_DROP_VIEW: @@ -4796,13 +4733,8 @@ end_with_restore_list: if (check_table_access(thd, DROP_ACL, all_tables, 0) || end_active_trans(thd)) goto error; - if (!(res= mysql_drop_view(thd, first_table, thd->lex->drop_mode)) && - mysql_bin_log.is_open()) - { - thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - } + /* Conditionally writes to binlog. */ + res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); break; } case SQLCOM_CREATE_TRIGGER: @@ -4810,6 +4742,7 @@ end_with_restore_list: if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog. */ res= mysql_create_or_drop_trigger(thd, all_tables, 1); /* We don't care about trigger body after this point */ @@ -4822,6 +4755,7 @@ end_with_restore_list: if (end_active_trans(thd)) goto error; + /* Conditionally writes to binlog. */ res= mysql_create_or_drop_trigger(thd, all_tables, 0); break; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 4772d64ad0a..403c5c8833e 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -3168,6 +3168,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (alter_info->tablespace_op != NO_TABLESPACE_OP) + /* Conditionally writes to binlog. */ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, alter_info->tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) @@ -3249,10 +3250,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, !table->s->tmp_table) // no need to touch frm { error=0; + VOID(pthread_mutex_lock(&LOCK_open)); if (new_name != table_name || new_db != db) { thd->proc_info="rename"; - VOID(pthread_mutex_lock(&LOCK_open)); /* Then do a 'simple' rename of the table */ error=0; if (!access(new_name_buff,F_OK)) @@ -3274,7 +3275,6 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, error= -1; } } - VOID(pthread_mutex_unlock(&LOCK_open)); } if (!error) @@ -3283,16 +3283,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, case LEAVE_AS_IS: break; case ENABLE: - VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - VOID(pthread_mutex_unlock(&LOCK_open)); error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: - VOID(pthread_mutex_lock(&LOCK_open)); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - VOID(pthread_mutex_unlock(&LOCK_open)); error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; @@ -3322,6 +3318,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, table->file->print_error(error, MYF(0)); error= -1; } + VOID(pthread_mutex_unlock(&LOCK_open)); table_list->table=0; // For query cache query_cache_invalidate3(thd, table_list, 0); DBUG_RETURN(error); @@ -3768,6 +3765,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, my_free((gptr) new_table,MYF(0)); goto err; } + /* + Writing to the binlog does not need to be synchronized for temporary tables, + which are thread-specific. + */ if (mysql_bin_log.is_open()) { thd->clear_error(); @@ -3950,7 +3951,7 @@ end_temporary: thd->some_tables_deleted=0; DBUG_RETURN(FALSE); - err: +err: DBUG_RETURN(TRUE); } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 66a16f16d8c..6ff8a0620f4 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -268,8 +268,6 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) table->triggers->drop_trigger(thd, tables)); end: - VOID(pthread_mutex_unlock(&LOCK_open)); - start_waiting_global_read_lock(thd); if (!result) { @@ -302,10 +300,14 @@ end: Query_log_event qinfo(thd, log_query.ptr(), log_query.length(), 0, FALSE); mysql_bin_log.write(&qinfo); } - - send_ok(thd); } + VOID(pthread_mutex_unlock(&LOCK_open)); + start_waiting_global_read_lock(thd); + + if (!result) + send_ok(thd); + DBUG_RETURN(result); } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 1561ade78af..a755a536b64 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -162,6 +162,7 @@ err: SYNOPSIS mysql_create_view() thd - thread handler + views - views to create mode - VIEW_CREATE_NEW, VIEW_ALTER, VIEW_CREATE_OR_REPLACE RETURN VALUE @@ -169,7 +170,7 @@ err: TRUE Error */ -bool mysql_create_view(THD *thd, +bool mysql_create_view(THD *thd, TABLE_LIST *views, enum_view_create_mode mode) { LEX *lex= thd->lex; @@ -490,6 +491,37 @@ bool mysql_create_view(THD *thd, } VOID(pthread_mutex_lock(&LOCK_open)); res= mysql_register_view(thd, view, mode); + + if (mysql_bin_log.is_open()) + { + String buff; + const LEX_STRING command[3]= + {{(char *)STRING_WITH_LEN("CREATE ")}, + {(char *)STRING_WITH_LEN("ALTER ")}, + {(char *)STRING_WITH_LEN("CREATE OR REPLACE ")}}; + + buff.append(command[thd->lex->create_view_mode].str, + command[thd->lex->create_view_mode].length); + view_store_options(thd, views, &buff); + buff.append(STRING_WITH_LEN("VIEW ")); + + /* Test if user supplied a db (ie: we did not use thd->db) */ + if (views->db && views->db[0] && + (thd->db == NULL || strcmp(views->db, thd->db))) + { + append_identifier(thd, &buff, views->db, + views->db_length); + buff.append('.'); + } + append_identifier(thd, &buff, views->table_name, + views->table_name_length); + buff.append(STRING_WITH_LEN(" AS ")); + buff.append(views->source.str, views->source.length); + + Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE); + mysql_bin_log.write(&qinfo); + } + VOID(pthread_mutex_unlock(&LOCK_open)); if (view->revision != 1) query_cache_invalidate3(thd, view, 0); @@ -1229,12 +1261,12 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) bool type= 0; db_type not_used; + VOID(pthread_mutex_lock(&LOCK_open)); for (view= views; view; view= view->next_local) { strxnmov(path, FN_REFLEN, mysql_data_home, "/", view->db, "/", view->table_name, reg_ext, NullS); (void) unpack_filename(path, path); - VOID(pthread_mutex_lock(&LOCK_open)); if (access(path, F_OK) || (type= (mysql_frm_type(thd, path, ¬_used) != FRMTYPE_VIEW))) { @@ -1245,7 +1277,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), name); - VOID(pthread_mutex_unlock(&LOCK_open)); continue; } if (type) @@ -1258,8 +1289,16 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) goto err; query_cache_invalidate3(thd, view, 0); sp_cache_invalidate(); - VOID(pthread_mutex_unlock(&LOCK_open)); } + + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } + + VOID(pthread_mutex_unlock(&LOCK_open)); send_ok(thd); DBUG_RETURN(FALSE); diff --git a/sql/sql_view.h b/sql/sql_view.h index cd61d7e9e71..9b6856b8c8a 100644 --- a/sql/sql_view.h +++ b/sql/sql_view.h @@ -16,7 +16,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -bool mysql_create_view(THD *thd, +bool mysql_create_view(THD *thd, TABLE_LIST *view, enum_view_create_mode mode); bool mysql_make_view(THD *thd, File_parser *parser, TABLE_LIST *table); From 25393e391be033a1f32b11f4ea1405f427930725 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 13:40:55 -0400 Subject: [PATCH 034/235] The behavior of "%p" varies. We prefer "0x%lx". --- vio/viosocket.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/vio/viosocket.c b/vio/viosocket.c index 710f7a93607..87fb1e107eb 100644 --- a/vio/viosocket.c +++ b/vio/viosocket.c @@ -33,7 +33,7 @@ int vio_read(Vio * vio, gptr buf, int size) { int r; DBUG_ENTER("vio_read"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); /* Ensure nobody uses vio_read_buff and vio_read simultaneously */ DBUG_ASSERT(vio->read_end == vio->read_pos); @@ -64,7 +64,7 @@ int vio_read_buff(Vio *vio, gptr buf, int size) int rc; #define VIO_UNBUFFERED_READ_MIN_SIZE 2048 DBUG_ENTER("vio_read_buff"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); if (vio->read_pos < vio->read_end) { @@ -102,7 +102,7 @@ int vio_write(Vio * vio, const gptr buf, int size) { int r; DBUG_ENTER("vio_write"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); #ifdef __WIN__ r = send(vio->sd, buf, size,0); #else @@ -397,7 +397,7 @@ int vio_read_pipe(Vio * vio, gptr buf, int size) { DWORD length; DBUG_ENTER("vio_read_pipe"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); if (!ReadFile(vio->hPipe, buf, size, &length, NULL)) DBUG_RETURN(-1); @@ -411,7 +411,7 @@ int vio_write_pipe(Vio * vio, const gptr buf, int size) { DWORD length; DBUG_ENTER("vio_write_pipe"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); if (!WriteFile(vio->hPipe, (char*) buf, size, &length, NULL)) DBUG_RETURN(-1); @@ -456,7 +456,7 @@ int vio_read_shared_memory(Vio * vio, gptr buf, int size) char *current_postion; DBUG_ENTER("vio_read_shared_memory"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); remain_local = size; current_postion=buf; @@ -517,7 +517,7 @@ int vio_write_shared_memory(Vio * vio, const gptr buf, int size) char *current_postion; DBUG_ENTER("vio_write_shared_memory"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); remain = size; current_postion = buf; From 14c2d195583136182ecde3b40c6b2f456c3b7b5a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 23:11:47 +0200 Subject: [PATCH 035/235] Fix problem when both option SSL and COMPRESS specified --- client/mysqltest.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index d057e7ea4f0..f52b4eafe15 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2991,7 +2991,12 @@ void do_connect(struct st_command *command) con_options= ds_options.str; while (*con_options) { - char* end= con_options; + char* end; + /* Step past any spaces in beginning of option*/ + while (*con_options && my_isspace(charset_info, *con_options)) + con_options++; + /* Find end of this option */ + end= con_options; while (*end && !my_isspace(charset_info, *end)) end++; if (!strncmp(con_options, "SSL", 3)) From 528b7ef9a6e95fb2660edab671ffadc2a7ebaee2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 01:20:08 +0200 Subject: [PATCH 036/235] Add possibility to send warnings about suspicious commands in .test file to .warnings file Move detection of "parsing enabled" to after command has been read. Cleanup parsing enabled/disabled --- client/mysqltest.c | 225 +++++++++++++++++++++++++++++++++------------ 1 file changed, 167 insertions(+), 58 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index f52b4eafe15..a81854733de 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -391,7 +391,7 @@ struct st_command TYPELIB command_typelib= {array_elements(command_names),"", command_names, 0}; -DYNAMIC_STRING ds_res, ds_progress; +DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages; void die(const char *fmt, ...) /* ATTRIBUTE_FORMAT(printf, 1, 2) */; @@ -399,6 +399,8 @@ void abort_not_supported_test(const char *fmt, ...) /* ATTRIBUTE_FORMAT(printf, 1, 2) */; void verbose_msg(const char *fmt, ...) /* ATTRIBUTE_FORMAT(printf, 1, 2) */; +void warning_msg(const char *fmt, ...) + /* ATTRIBUTE_FORMAT(printf, 1, 2) */; VAR* var_from_env(const char *, const char *); VAR* var_init(VAR* v, const char *name, int name_len, const char *val, @@ -410,6 +412,7 @@ void eval_expr(VAR* v, const char *p, const char** p_end); my_bool match_delimiter(int c, const char *delim, uint length); void dump_result_to_reject_file(const char *record_file, char *buf, int size); void dump_result_to_log_file(const char *record_file, char *buf, int size); +void dump_warning_messages(const char *record_file); void do_eval(DYNAMIC_STRING *query_eval, const char *query, const char *query_end, my_bool pass_through_escape_chars); @@ -697,6 +700,7 @@ void free_used_memory() delete_dynamic(&q_lines); dynstr_free(&ds_res); dynstr_free(&ds_progress); + dynstr_free(&ds_warning_messages); free_all_replace(); my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); free_defaults(default_argv); @@ -741,6 +745,10 @@ void die(const char *fmt, ...) if (result_file && ds_res.length) dump_result_to_log_file(result_file, ds_res.str, ds_res.length); + /* Dump warning messages */ + if (result_file && ds_warning_messages.length) + dump_warning_messages(result_file); + /* Clean up and exit */ free_used_memory(); my_end(MY_CHECK_ERROR); @@ -817,6 +825,31 @@ void verbose_msg(const char *fmt, ...) } +void warning_msg(const char *fmt, ...) +{ + va_list args; + char buff[512]; + size_t len; + DBUG_ENTER("warning_msg"); + + va_start(args, fmt); + dynstr_append(&ds_warning_messages, "mysqltest: "); + if (start_lineno != 0) + { + len= my_snprintf(buff, sizeof(buff), "Warning detected at line %d: ", + start_lineno); + dynstr_append_mem(&ds_warning_messages, + buff, len); + } + len= vsnprintf(buff, sizeof(buff), fmt, args); + dynstr_append_mem(&ds_warning_messages, buff, len); + dynstr_append(&ds_warning_messages, "\n"); + va_end(args); + + DBUG_VOID_RETURN; +} + + /* Compare content of the string ds to content of file fname */ @@ -3495,6 +3528,55 @@ void convert_to_format_v1(char* query) } +/* + Check a command that is about to be sent (or should have been + sent if parsing was enabled) to mysql server for + suspicious things and generate warnings. +*/ + +void scan_command_for_warnings(struct st_command *command) +{ + const char *ptr= command->query; + DBUG_ENTER("scan_command_for_warnings"); + DBUG_PRINT("enter", ("query: %s", command->query)); + + while(*ptr) + { + /* + Look for query's that lines that start with a -- comment + and has a mysqltest command + */ + if (ptr[0] == '\n' && + ptr[1] && ptr[1] == '-' && + ptr[2] && ptr[2] == '-' && + ptr[3]) + { + uint type; + char save; + char *end, *start= (char*)ptr+3; + /* Skip leading spaces */ + while (*start && my_isspace(charset_info, *start)) + start++; + end= start; + /* Find end of command(next space) */ + while (*end && !my_isspace(charset_info, *end)) + end++; + save= *end; + *end= 0; + DBUG_PRINT("info", ("Checking '%s'", start)); + type= find_type(start, &command_typelib, 1+2); + if (type) + warning_msg("Embedded mysqltest command '--%s' detected in " + "query '%s' was this intentional? ", + start, command->query); + *end= save; + } + + *ptr++; + } + DBUG_VOID_RETURN; +} + /* Check for unexpected "junk" after the end of query This is normally caused by missing delimiters @@ -3583,43 +3665,29 @@ int read_command(struct st_command** command_ptr) if (*p == '#') { command->type= Q_COMMENT; - /* This goto is to avoid losing the "expected error" info. */ - goto end; } - if (!parsing_disabled) - { - memcpy(&command->expected_errors, &saved_expected_errors, - sizeof(saved_expected_errors)); - DBUG_PRINT("info", ("There are %d expected errors", - command->expected_errors.count)); - command->abort_on_error= (command->expected_errors.count == 0 && - abort_on_error); - } - - if (p[0] == '-' && p[1] == '-') + else if (p[0] == '-' && p[1] == '-') { command->type= Q_COMMENT_WITH_COMMAND; - p+= 2; /* To calculate first word */ - } - else if (!parsing_disabled) - { - while (*p && my_isspace(charset_info, *p)) - p++ ; + p+= 2; /* Skip past -- */ } -end: + /* Skip leading spaces */ while (*p && my_isspace(charset_info, *p)) p++; if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME)))) - die(NullS); + die("Out of memory"); /* Calculate first word and first argument */ for (p= command->query; *p && !my_isspace(charset_info, *p) ; p++) ; command->first_word_len= (uint) (p - command->query); + + /* Skip spaces between command and first argument */ while (*p && my_isspace(charset_info, *p)) p++; command->first_argument= p; + command->end= strend(command->query); command->query_len= (command->end - command->query); parser.read_lines++; @@ -3947,6 +4015,15 @@ void dump_progress(const char *record_file) ds_progress.str, ds_progress.length); } +void dump_warning_messages(const char *record_file) +{ + char warn_file[FN_REFLEN]; + + str_to_file(fn_format(warn_file, record_file, "", ".warnings", + MY_REPLACE_EXT), + ds_warning_messages.str, ds_warning_messages.length); +} + void check_regerr(my_regex_t* r, int err) { char err_buf[1024]; @@ -4880,6 +4957,9 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags) init_dynamic_string(&ds_warnings, NULL, 0, 256); + /* Scan for warning before sendign to server */ + scan_command_for_warnings(command); + /* Evaluate query if this is an eval command */ @@ -5166,28 +5246,19 @@ void get_command_type(struct st_command* command) uint type; DBUG_ENTER("get_command_type"); - if (!parsing_disabled && *command->query == '}') + if (*command->query == '}') { command->type = Q_END_BLOCK; DBUG_VOID_RETURN; } - if (command->type != Q_COMMENT_WITH_COMMAND) - command->type= parsing_disabled ? Q_COMMENT : Q_QUERY; - save=command->query[command->first_word_len]; - command->query[command->first_word_len]=0; - type=find_type(command->query, &command_typelib, 1+2); - command->query[command->first_word_len]=save; + save= command->query[command->first_word_len]; + command->query[command->first_word_len]= 0; + type= find_type(command->query, &command_typelib, 1+2); + command->query[command->first_word_len]= save; if (type > 0) { command->type=(enum enum_commands) type; /* Found command */ - /* - If queries are disabled, only recognize - --enable_parsing and --disable_parsing - */ - if (parsing_disabled && command->type != Q_ENABLE_PARSING && - command->type != Q_DISABLE_PARSING) - command->type= Q_COMMENT; /* Look for case where "query" was explicitly specified to @@ -5199,23 +5270,50 @@ void get_command_type(struct st_command* command) command->query= command->first_argument; } } - else if (command->type == Q_COMMENT_WITH_COMMAND && - command->first_word_len && - strcmp(command->query + command->first_word_len - 1, delimiter) == 0) + else { - /* - Detect comment with command using extra delimiter - Ex --disable_query_log; - ^ Extra delimiter causing the command - to be skipped - */ - save= command->query[command->first_word_len-1]; - command->query[command->first_word_len-1]= 0; - type= find_type(command->query, &command_typelib, 1+2); - command->query[command->first_word_len-1]= save; - if (type > 0) - die("Extra delimiter \";\" found"); + /* No mysqltest command matched */ + + if (command->type != Q_COMMENT_WITH_COMMAND) + { + /* A query that will sent to mysqld */ + command->type= Q_QUERY; + } + else + { + /* -- comment that didn't contain a mysqltest command */ + command->type= Q_COMMENT; + warning_msg("Suspicious command '--%s' detected, was this intentional? "\ + "Use # instead of -- to avoid this warning", + command->query); + + if (command->first_word_len && + strcmp(command->query + command->first_word_len - 1, delimiter) == 0) + { + /* + Detect comment with command using extra delimiter + Ex --disable_query_log; + ^ Extra delimiter causing the command + to be skipped + */ + save= command->query[command->first_word_len-1]; + command->query[command->first_word_len-1]= 0; + if (find_type(command->query, &command_typelib, 1+2) > 0) + die("Extra delimiter \";\" found"); + command->query[command->first_word_len-1]= save; + + } + } } + + /* Set expected error on command */ + memcpy(&command->expected_errors, &saved_expected_errors, + sizeof(saved_expected_errors)); + DBUG_PRINT("info", ("There are %d expected errors", + command->expected_errors.count)); + command->abort_on_error= (command->expected_errors.count == 0 && + abort_on_error); + DBUG_VOID_RETURN; } @@ -5314,6 +5412,7 @@ int main(int argc, char **argv) init_dynamic_string(&ds_res, "", 65536, 65536); init_dynamic_string(&ds_progress, "", 0, 2048); + init_dynamic_string(&ds_warning_messages, "", 0, 2048); parse_args(argc, argv); DBUG_PRINT("info",("result_file: '%s'", result_file ? result_file : "")); @@ -5386,6 +5485,15 @@ int main(int argc, char **argv) int current_line_inc = 1, processed = 0; if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND) get_command_type(command); + + if (parsing_disabled && + command->type != Q_ENABLE_PARSING && + command->type != Q_DISABLE_PARSING) + { + command->type= Q_COMMENT; + scan_command_for_warnings(command); + } + if (cur_block->ok) { command->last_argument= command->first_argument; @@ -5558,7 +5666,6 @@ int main(int argc, char **argv) break; } case Q_COMMENT: /* Ignore row */ - case Q_COMMENT_WITH_COMMAND: command->last_argument= command->end; break; case Q_PING: @@ -5631,10 +5738,11 @@ int main(int argc, char **argv) else check_eol_junk(command->last_argument); - if (command->type != Q_ERROR) + if (command->type != Q_ERROR && + command->type != Q_COMMENT) { /* - As soon as any non "error" command has been executed, + As soon as any non "error" command or comment has been executed, the array with expected errors should be cleared */ memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); @@ -5650,8 +5758,6 @@ int main(int argc, char **argv) } last_command_executed= command_executed; - - parser.current_line += current_line_inc; if ( opt_mark_progress ) mark_progress(command, parser.current_line); @@ -5708,9 +5814,12 @@ int main(int argc, char **argv) die("No queries executed but result file found!"); } - if ( opt_mark_progress ) + if ( opt_mark_progress && result_file ) dump_progress(result_file); - dynstr_free(&ds_progress); + + /* Dump warning messages */ + if (result_file && ds_warning_messages.length) + dump_warning_messages(result_file); dynstr_free(&ds_res); From 0d833887e2cf72e99168649165fdd6dd94425b95 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 3 Oct 2006 21:26:55 -0600 Subject: [PATCH 037/235] Bug #19764: SHOW commands end up in the slow log as table scans Set a flag when a SHOW command is parsed, and check it in log_slow_statement(). SHOW commands are not counted as slow queries, even if they use table scans. mysql-test/t/show_check-master.opt: BitKeeper file /usr/home/tim/m/bk/b19764/50/mysql-test/t/show_check-master.opt mysql-test/r/show_check.result: Add test for bug #19764 mysql-test/t/show_check.test: Add test for bug #19764 sql/sql_lex.cc: Set lex->is_show_command= FALSE in lex_start sql/sql_lex.h: Add LEX->is_slow_command flag to prevent SHOW commands from being written to the slow queries log sql/sql_parse.cc: Don't log slow statement if it is a SHOW command sql/sql_yacc.yy: Set lex->is_show_command for all SHOW commands --- mysql-test/r/show_check.result | 17 +++++++++++++++++ mysql-test/t/show_check-master.opt | 1 + mysql-test/t/show_check.test | 17 +++++++++++++++-- sql/sql_lex.cc | 1 + sql/sql_lex.h | 7 +++++++ sql/sql_parse.cc | 6 +++--- sql/sql_yacc.yy | 1 + 7 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 mysql-test/t/show_check-master.opt diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 7bdfa78066c..3c90af924e4 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -520,6 +520,7 @@ t1 NULL NULL NULL NULL # # # # NULL NULL NULL NULL NULL NULL NULL NULL Incorrect show create table t1; ERROR HY000: Incorrect information in file: './test/t1.frm' drop table t1; +End of 4.1 tests CREATE TABLE txt1(a int); CREATE TABLE tyt2(a int); CREATE TABLE urkunde(a int); @@ -629,3 +630,19 @@ SHOW TABLES FROM no_such_database; ERROR 42000: Unknown database 'no_such_database' SHOW COLUMNS FROM no_such_table; ERROR 42S02: Table 'test.no_such_table' doesn't exist +flush status; +show status like 'slow_queries'; +Variable_name Value +Slow_queries 0 +show tables; +Tables_in_test +show status like 'slow_queries'; +Variable_name Value +Slow_queries 0 +select 1 from information_schema.tables limit 1; +1 +1 +show status like 'slow_queries'; +Variable_name Value +Slow_queries 1 +End of 5.0 tests. diff --git a/mysql-test/t/show_check-master.opt b/mysql-test/t/show_check-master.opt new file mode 100644 index 00000000000..3eb98fc3d6b --- /dev/null +++ b/mysql-test/t/show_check-master.opt @@ -0,0 +1 @@ +--log-slow-queries --log-long-format --log-queries-not-using-indexes diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 65a81545c87..1fc22e38f73 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -400,7 +400,8 @@ show create table t1; drop table t1; -# End of 4.1 tests +--echo End of 4.1 tests + # # BUG 12183 - SHOW OPEN TABLES behavior doesn't match grammar # First we close all open tables with FLUSH tables and then we open some. @@ -506,4 +507,16 @@ SHOW TABLES FROM no_such_database; SHOW COLUMNS FROM no_such_table; -# End of 5.0 tests. +# +# Bug #19764: SHOW commands end up in the slow log as table scans +# +flush status; +show status like 'slow_queries'; +show tables; +show status like 'slow_queries'; +# Table scan query, to ensure that slow_queries does still get incremented +# (mysqld is started with --log-queries-not-using-indexes) +select 1 from information_schema.tables limit 1; +show status like 'slow_queries'; + +--echo End of 5.0 tests. diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 788276ac654..01db96291ff 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -173,6 +173,7 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->spcont= NULL; lex->proc_list.first= 0; lex->escape_used= FALSE; + lex->is_show_command= FALSE; lex->reset_query_tables_list(FALSE); lex->nest_level=0 ; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index fdf14c691e9..1eae81732b7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1016,6 +1016,13 @@ typedef struct st_lex : public Query_tables_list bool escape_used; + /* + Prevent SHOW commands from being written to the slow queries log. + This is fixed properly in MySQL 5.1, but a quick hack is used in 5.0 + to achieve the same result. + */ + bool is_show_command; + st_lex(); virtual ~st_lex() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 18d048df393..90cef7796fb 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2150,10 +2150,10 @@ void log_slow_statement(THD *thd) thd->end_time(); // Set start time /* - Do not log administrative statements unless the appropriate option is - set; do not log into slow log if reading from backup. + Do not log administrative or SHOW statements unless the appropriate + option is set; do not log into slow log if reading from backup. */ - if (thd->enable_slow_log && !thd->user_time) + if (thd->enable_slow_log && !thd->user_time && !thd->lex->is_show_command) { thd->proc_info="logging slow query"; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index cb105d05332..3d31b37062c 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6412,6 +6412,7 @@ opt_table_sym: show: SHOW { LEX *lex=Lex; + lex->is_show_command= TRUE; lex->wild=0; lex->lock_option= TL_READ; mysql_init_select(lex); From 99cfe38ae7d6da2dca8a3b377254d0bfba8b6ac4 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 12:27:05 +0200 Subject: [PATCH 038/235] Don't print version in error message, just too messy to test --- client/mysqltest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index a81854733de..d49693fa324 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -802,7 +802,7 @@ void abort_not_supported_test(const char *fmt, ...) void abort_not_in_this_version() { - die("Not available in mysqltest for MySQL %s", VERSION); + die("Not available in this version of mysqltest"); } From dccc6b10c34cc111e6a587642b4e7eb93bd3b6a1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 12:47:32 +0200 Subject: [PATCH 039/235] Backport from 5.1 -Add support for detecting version and features from mysqld binary - Autodetect netware - Disable some features not available below 5.0 - Cleanup executable_setup to look for one executable at a time, only llok for the ones that are needed based on the selected testcases and settings mysql-test/lib/mtr_cases.pl: Backport from 5.1 mysql-test/lib/mtr_io.pl: Backport from 5.1 Add new function mtr_appendfile_to_file mysql-test/lib/mtr_misc.pl: Backport from 5.1 mysql-test/lib/mtr_process.pl: Backport from 5.1 mysql-test/lib/mtr_report.pl: Backport from 5.1 mysql-test/mysql-test-run.pl: Add support for detecting version and features from mysqld binary Autodetect netware Disable some features not available below 5.0 Cleanup executable_setup to look for one executable at a time, only llok for the ones that are needed based on the selected testcases and settings mysql-test/r/mysqltest.result: Update result mysql-test/lib/mtr_im.pl: New BitKeeper file ``mysql-test/lib/mtr_im.pl'' mysql-test/lib/mtr_stress.pl: New BitKeeper file ``mysql-test/lib/mtr_stress.pl'' --- mysql-test/lib/mtr_cases.pl | 367 +++- mysql-test/lib/mtr_im.pl | 761 +++++++ mysql-test/lib/mtr_io.pl | 66 +- mysql-test/lib/mtr_misc.pl | 40 +- mysql-test/lib/mtr_process.pl | 709 +++--- mysql-test/lib/mtr_report.pl | 135 +- mysql-test/lib/mtr_stress.pl | 178 ++ mysql-test/mysql-test-run.pl | 3821 ++++++++++++++++++++++++--------- mysql-test/r/mysqltest.result | 2 +- 9 files changed, 4681 insertions(+), 1398 deletions(-) create mode 100644 mysql-test/lib/mtr_im.pl create mode 100644 mysql-test/lib/mtr_stress.pl diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 650fb79155d..bb92730444c 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -5,10 +5,13 @@ # same name. use File::Basename; +use IO::File(); use strict; sub collect_test_cases ($); -sub collect_one_test_case ($$$$$$); +sub collect_one_test_case ($$$$$$$); + +sub mtr_options_from_test_file($$); ############################################################################## # @@ -37,44 +40,114 @@ sub collect_test_cases ($) { opendir(TESTDIR, $testdir) or mtr_error("Can't open dir \"$testdir\": $!"); + # ---------------------------------------------------------------------- + # Disable some tests listed in disabled.def + # ---------------------------------------------------------------------- + my %disabled; + if ( open(DISABLED, "$testdir/disabled.def" ) ) + { + while ( ) + { + chomp; + if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ ) + { + $disabled{$1}= $2; + } + } + close DISABLED; + } + if ( @::opt_cases ) { foreach my $tname ( @::opt_cases ) { # Run in specified order, no sort - $tname= basename($tname, ".test"); - my $elem= "$tname.test"; - if ( ! -f "$testdir/$elem") + my $elem= undef; + my $component_id= undef; + + # Get rid of directory part (path). Leave the extension since it is used + # to understand type of the test. + + $tname = basename($tname); + + # Check if the extenstion has been specified. + + if ( mtr_match_extension($tname, "test") ) { - mtr_error("Test case $tname ($testdir/$elem) is not found"); + $elem= $tname; + $tname=~ s/\.test$//; + $component_id= 'mysqld'; } - collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,{}); + elsif ( mtr_match_extension($tname, "imtest") ) + { + $elem= $tname; + $tname =~ s/\.imtest$//; + $component_id= 'im'; + } + + # If target component is known, check that the specified test case + # exists. + # + # Otherwise, try to guess the target component. + + if ( $component_id ) + { + if ( ! -f "$testdir/$elem") + { + mtr_error("Test case $tname ($testdir/$elem) is not found"); + } + } + else + { + my $mysqld_test_exists = -f "$testdir/$tname.test"; + my $im_test_exists = -f "$testdir/$tname.imtest"; + + if ( $mysqld_test_exists and $im_test_exists ) + { + mtr_error("Ambiguous test case name ($tname)"); + } + elsif ( ! $mysqld_test_exists and ! $im_test_exists ) + { + mtr_error("Test case $tname is not found"); + } + elsif ( $mysqld_test_exists ) + { + $elem= "$tname.test"; + $component_id= 'mysqld'; + } + elsif ( $im_test_exists ) + { + $elem= "$tname.imtest"; + $component_id= 'im'; + } + } + + collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, + $component_id); } closedir TESTDIR; } else { - # ---------------------------------------------------------------------- - # Disable some tests listed in disabled.def - # ---------------------------------------------------------------------- - my %disabled; - if ( open(DISABLED, "$testdir/disabled.def" ) ) - { - while ( ) - { - chomp; - if ( /^\s*(\S+)\s*:\s*(.*?)\s*$/ ) - { - $disabled{$1}= $2; - } - } - close DISABLED; - } - foreach my $elem ( sort readdir(TESTDIR) ) { - my $tname= mtr_match_extension($elem,"test"); - next if ! defined $tname; + my $component_id= undef; + my $tname= undef; + + if ($tname= mtr_match_extension($elem, 'test')) + { + $component_id = 'mysqld'; + } + elsif ($tname= mtr_match_extension($elem, 'imtest')) + { + $component_id = 'im'; + } + else + { + next; + } + next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test); - collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled); + collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, + $component_id); } closedir TESTDIR; } @@ -84,34 +157,38 @@ sub collect_test_cases ($) { if ( $::opt_reorder ) { - @$cases = sort { - if ( ! $a->{'master_restart'} and ! $b->{'master_restart'} ) - { - return $a->{'name'} cmp $b->{'name'}; - } - if ( $a->{'master_restart'} and $b->{'master_restart'} ) - { - my $cmp= mtr_cmp_opts($a->{'master_opt'}, $b->{'master_opt'}); - if ( $cmp == 0 ) - { - return $a->{'name'} cmp $b->{'name'}; - } - else - { - return $cmp; - } - } + my %sort_criteria; + my $tinfo; - if ( $a->{'master_restart'} ) - { - return 1; # Is greater - } - else - { - return -1; # Is less - } - } @$cases; + # Make a mapping of test name to a string that represents how that test + # should be sorted among the other tests. Put the most important criterion + # first, then a sub-criterion, then sub-sub-criterion, et c. + foreach $tinfo (@$cases) + { + my @this_criteria = (); + + # Append the criteria for sorting, in order of importance. + push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); # Ending with "~" makes empty sort later than filled + push(@this_criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); + push(@this_criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); + push(@this_criteria, "big_test=" . ($tinfo->{'big_test'} ? "1" : "0")); + push(@this_criteria, join("|", sort keys %{$tinfo})); # Group similar things together. The values may differ substantially. FIXME? + push(@this_criteria, $tinfo->{'name'}); # Finally, order by the name + + $sort_criteria{$tinfo->{"name"}} = join(" ", @this_criteria); + } + + @$cases = sort { $sort_criteria{$a->{"name"}} cmp $sort_criteria{$b->{"name"}}; } @$cases; + +### For debugging the sort-order +# foreach $tinfo (@$cases) +# { +# print $sort_criteria{$tinfo->{"name"}}; +# print " -> \t"; +# print $tinfo->{"name"}; +# print "\n"; +# } } return $cases; @@ -125,13 +202,14 @@ sub collect_test_cases ($) { ############################################################################## -sub collect_one_test_case($$$$$$) { +sub collect_one_test_case($$$$$$$) { my $testdir= shift; my $resdir= shift; my $tname= shift; my $elem= shift; my $cases= shift; my $disabled=shift; + my $component_id= shift; my $path= "$testdir/$elem"; @@ -151,6 +229,7 @@ sub collect_one_test_case($$$$$$) { my $tinfo= {}; $tinfo->{'name'}= $tname; $tinfo->{'result_file'}= "$resdir/$tname.result"; + $tinfo->{'component_id'} = $component_id; push(@$cases, $tinfo); if ( $::opt_skip_test and defined mtr_match_prefix($tname,$::opt_skip_test) ) @@ -171,48 +250,54 @@ sub collect_one_test_case($$$$$$) { if ( $::opt_skip_rpl ) { $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No replication tests(--skip-rpl)"; return; } $tinfo->{'slave_num'}= 1; # Default, use one slave - # FIXME currently we always restart slaves - $tinfo->{'slave_restart'}= 1; - if ( $tname eq 'rpl_failsafe' or $tname eq 'rpl_chain_temp_table' ) { -# $tinfo->{'slave_num'}= 3; # Not 3 ? Check old code, strange + # $tinfo->{'slave_num'}= 3; # Not 3 ? Check old code, strange } } if ( defined mtr_match_prefix($tname,"federated") ) { - $tinfo->{'slave_num'}= 1; # Default, use one slave - - # FIXME currently we always restart slaves - $tinfo->{'slave_restart'}= 1; + # Default, federated uses the first slave as it's federated database + $tinfo->{'slave_num'}= 1; } - # Cluster is needed by test case if testname contains ndb - if ( defined mtr_match_substring($tname,"ndb") ) + if ( $::opt_with_ndbcluster or defined mtr_match_substring($tname,"ndb") ) { + # This is an ndb test or all tests should be run with ndb cluster started $tinfo->{'ndb_test'}= 1; if ( $::opt_skip_ndbcluster ) { - # Skip all ndb tests + # All ndb test's should be skipped $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No ndbcluster test(--skip-ndbcluster)"; return; } - if ( ! $::opt_with_ndbcluster ) + if ( ! $::opt_ndbcluster_supported ) { # Ndb is not supported, skip them $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No ndbcluster support"; return; } } else { + # This is not a ndb test $tinfo->{'ndb_test'}= 0; + if ( $::opt_with_ndbcluster_only ) + { + # Only the ndb test should be run, all other should be skipped + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)"; + return; + } } # FIXME what about embedded_server + ndbcluster, skip ?! @@ -223,6 +308,7 @@ sub collect_one_test_case($$$$$$) { my $master_sh= "$testdir/$tname-master.sh"; my $slave_sh= "$testdir/$tname-slave.sh"; my $disabled_file= "$testdir/$tname.disabled"; + my $im_opt_file= "$testdir/$tname-im.opt"; $tinfo->{'master_opt'}= []; $tinfo->{'slave_opt'}= []; @@ -303,6 +389,8 @@ sub collect_one_test_case($$$$$$) { if ( $::glob_win32_perl ) { $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No tests with sh scripts on Windows"; + return; } else { @@ -316,6 +404,8 @@ sub collect_one_test_case($$$$$$) { if ( $::glob_win32_perl ) { $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No tests with sh scripts on Windows"; + return; } else { @@ -324,29 +414,166 @@ sub collect_one_test_case($$$$$$) { } } + if ( -f $im_opt_file ) + { + $tinfo->{'im_opts'} = mtr_get_opts_from_file($im_opt_file); + } + else + { + $tinfo->{'im_opts'} = []; + } + # FIXME why this late? + my $marked_as_disabled= 0; if ( $disabled->{$tname} ) { - $tinfo->{'skip'}= 1; - $tinfo->{'disable'}= 1; # Sub type of 'skip' - $tinfo->{'comment'}= $disabled->{$tname} if $disabled->{$tname}; + $marked_as_disabled= 1; + $tinfo->{'comment'}= $disabled->{$tname}; } if ( -f $disabled_file ) { - $tinfo->{'skip'}= 1; - $tinfo->{'disable'}= 1; # Sub type of 'skip' + $marked_as_disabled= 1; $tinfo->{'comment'}= mtr_fromfile($disabled_file); } + # If test was marked as disabled, either opt_enable_disabled is off and then + # we skip this test, or it is on and then we run this test but warn + + if ( $marked_as_disabled ) + { + if ( $::opt_enable_disabled ) + { + $tinfo->{'dont_skip_though_disabled'}= 1; + } + else + { + $tinfo->{'skip'}= 1; + $tinfo->{'disable'}= 1; # Sub type of 'skip' + return; + } + } + + if ( $component_id eq 'im' ) + { + if ( $::glob_use_embedded_server ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No IM with embedded server"; + return; + } + elsif ( $::opt_ps_protocol ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No IM with --ps-protocol"; + return; + } + elsif ( $::opt_skip_im ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No IM tests(--skip-im)"; + return; + } + } + else + { + mtr_options_from_test_file($tinfo,"$testdir/${tname}.test"); + + if ( $tinfo->{'big_test'} and ! $::opt_big_test ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test need 'big-test' option"; + return; + } + + if ( $tinfo->{'ndb_extra'} and ! $::opt_ndb_extra_test ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test need 'ndb_extra' option"; + return; + } + + if ( $tinfo->{'require_manager'} ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test need the _old_ manager(to be removed)"; + return; + } + + if ( defined $tinfo->{'binlog_format'} and + ! ( $tinfo->{'binlog_format'} eq $::used_binlog_format ) ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Not running with binlog format '$tinfo->{'binlog_format'}'"; + return; + } + + if ( $tinfo->{'need_debug'} && ! $::debug_compiled_binaries ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Test need debug binaries"; + return; + } + } + # We can't restart a running server that may be in use if ( $::glob_use_running_server and ( $tinfo->{'master_restart'} or $tinfo->{'slave_restart'} ) ) { $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Can't restart a running server"; + return; } + } +# List of tags in the .test files that if found should set +# the specified value in "tinfo" +our @tags= +( + ["include/have_innodb.inc", "innodb_test", 1], + ["include/have_binlog_format_row.inc", "binlog_format", "row"], + ["include/have_binlog_format_statement.inc", "binlog_format", "stmt"], + ["include/big_test.inc", "big_test", 1], + ["include/have_debug.inc", "need_debug", 1], + ["include/have_ndb_extra.inc", "ndb_extra", 1], + ["require_manager", "require_manager", 1], +); + +sub mtr_options_from_test_file($$) { + my $tinfo= shift; + my $file= shift; + #mtr_verbose("$file"); + my $F= IO::File->new($file) or mtr_error("can't open file \"$file\": $!"); + + while ( my $line= <$F> ) + { + next if ( $line !~ /^--/ ); + + # Match this line against tag in "tags" array + foreach my $tag (@tags) + { + if ( index($line, $tag->[0]) >= 0 ) + { + # Tag matched, assign value to "tinfo" + $tinfo->{"$tag->[1]"}= $tag->[2]; + } + } + + # If test sources another file, open it as well + if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ ) + { + my $value= $2; + $value =~ s/^\s+//; # Remove leading space + $value =~ s/[[:space:]]+$//; # Remove ending space + + my $sourced_file= "$::glob_mysql_test_dir/$value"; + mtr_options_from_test_file($tinfo, $sourced_file); + } + + } +} + 1; diff --git a/mysql-test/lib/mtr_im.pl b/mysql-test/lib/mtr_im.pl new file mode 100644 index 00000000000..ca17516278e --- /dev/null +++ b/mysql-test/lib/mtr_im.pl @@ -0,0 +1,761 @@ +# -*- cperl -*- + +# This is a library file used by the Perl version of mysql-test-run, +# and is part of the translation of the Bourne shell script with the +# same name. + +use strict; + +# Private IM-related operations. + +sub mtr_im_kill_process ($$$$); +sub mtr_im_load_pids ($); +sub mtr_im_terminate ($); +sub mtr_im_check_alive ($); +sub mtr_im_check_main_alive ($); +sub mtr_im_check_angel_alive ($); +sub mtr_im_check_mysqlds_alive ($); +sub mtr_im_check_mysqld_alive ($); +sub mtr_im_cleanup ($); +sub mtr_im_rm_file ($); +sub mtr_im_errlog ($); +sub mtr_im_kill ($); +sub mtr_im_wait_for_connection ($$$); +sub mtr_im_wait_for_mysqld($$$); + +# Public IM-related operations. + +sub mtr_im_start ($$); +sub mtr_im_stop ($); + +############################################################################## +# +# Private operations. +# +############################################################################## + +sub mtr_im_kill_process ($$$$) { + my $pid_lst= shift; + my $signal= shift; + my $total_retries= shift; + my $timeout= shift; + + my %pids; + + foreach my $pid ( @{$pid_lst} ) + { + $pids{$pid}= 1; + } + + for ( my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt ) + { + foreach my $pid ( keys %pids ) + { + mtr_debug("Sending $signal to $pid..."); + + kill($signal, $pid); + + unless ( kill (0, $pid) ) + { + mtr_debug("Process $pid died."); + delete $pids{$pid}; + } + } + + return if scalar keys %pids == 0; + + mtr_debug("Sleeping $timeout second(s) waiting for processes to die..."); + + sleep($timeout); + } + + mtr_debug("Process(es) " . + join(' ', keys %pids) . + " is still alive after $total_retries " . + "of sending signal $signal."); +} + +########################################################################### + +sub mtr_im_load_pids($) { + my $im= shift; + + mtr_debug("Loading PID files..."); + + # Obtain mysqld-process pids. + + my $instances = $im->{'instances'}; + + for ( my $idx= 0; $idx < 2; ++$idx ) + { + mtr_debug("IM-guarded mysqld[$idx] PID file: '" . + $instances->[$idx]->{'path_pid'} . "'."); + + my $mysqld_pid; + + if ( -r $instances->[$idx]->{'path_pid'} ) + { + $mysqld_pid= mtr_get_pid_from_file($instances->[$idx]->{'path_pid'}); + mtr_debug("IM-guarded mysqld[$idx] PID: $mysqld_pid."); + } + else + { + $mysqld_pid= undef; + mtr_debug("IM-guarded mysqld[$idx]: no PID file."); + } + + $instances->[$idx]->{'pid'}= $mysqld_pid; + } + + # Re-read Instance Manager PIDs from the file, since during tests Instance + # Manager could have been restarted, so its PIDs could have been changed. + + # - IM-main + + mtr_debug("IM-main PID file: '$im->{path_pid}'."); + + if ( -f $im->{'path_pid'} ) + { + $im->{'pid'} = + mtr_get_pid_from_file($im->{'path_pid'}); + + mtr_debug("IM-main PID: $im->{pid}."); + } + else + { + mtr_debug("IM-main: no PID file."); + $im->{'pid'}= undef; + } + + # - IM-angel + + mtr_debug("IM-angel PID file: '$im->{path_angel_pid}'."); + + if ( -f $im->{'path_angel_pid'} ) + { + $im->{'angel_pid'} = + mtr_get_pid_from_file($im->{'path_angel_pid'}); + + mtr_debug("IM-angel PID: $im->{'angel_pid'}."); + } + else + { + mtr_debug("IM-angel: no PID file."); + $im->{'angel_pid'} = undef; + } +} + +########################################################################### + +sub mtr_im_terminate($) { + my $im= shift; + + # Load pids from pid-files. We should do it first of all, because IM deletes + # them on shutdown. + + mtr_im_load_pids($im); + + mtr_debug("Shutting Instance Manager down..."); + + # Ignoring SIGCHLD so that all children could rest in peace. + + start_reap_all(); + + # Send SIGTERM to IM-main. + + if ( defined $im->{'pid'} ) + { + mtr_debug("IM-main pid: $im->{pid}."); + mtr_debug("Stopping IM-main..."); + + mtr_im_kill_process([ $im->{'pid'} ], 'TERM', 10, 1); + } + else + { + mtr_debug("IM-main pid: n/a."); + } + + # If IM-angel was alive, wait for it to die. + + if ( defined $im->{'angel_pid'} ) + { + mtr_debug("IM-angel pid: $im->{'angel_pid'}."); + mtr_debug("Waiting for IM-angel to die..."); + + my $total_attempts= 10; + + for ( my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt ) + { + unless ( kill (0, $im->{'angel_pid'}) ) + { + mtr_debug("IM-angel died."); + last; + } + + sleep(1); + } + } + else + { + mtr_debug("IM-angel pid: n/a."); + } + + stop_reap_all(); + + # Re-load PIDs. + + mtr_im_load_pids($im); +} + +########################################################################### + +sub mtr_im_check_alive($) { + my $im= shift; + + mtr_debug("Checking whether IM-components are alive..."); + + return 1 if mtr_im_check_main_alive($im); + + return 1 if mtr_im_check_angel_alive($im); + + return 1 if mtr_im_check_mysqlds_alive($im); + + return 0; +} + +########################################################################### + +sub mtr_im_check_main_alive($) { + my $im= shift; + + # Check that the process, that we know to be IM's, is dead. + + if ( defined $im->{'pid'} ) + { + if ( kill (0, $im->{'pid'}) ) + { + mtr_debug("IM-main (PID: $im->{pid}) is alive."); + return 1; + } + else + { + mtr_debug("IM-main (PID: $im->{pid}) is dead."); + } + } + else + { + mtr_debug("No PID file for IM-main."); + } + + # Check that IM does not accept client connections. + + if ( mtr_ping_port($im->{'port'}) ) + { + mtr_debug("IM-main (port: $im->{port}) " . + "is accepting connections."); + + mtr_im_errlog("IM-main is accepting connections on port " . + "$im->{port}, but there is no " . + "process information."); + return 1; + } + else + { + mtr_debug("IM-main (port: $im->{port}) " . + "does not accept connections."); + return 0; + } +} + +########################################################################### + +sub mtr_im_check_angel_alive($) { + my $im= shift; + + # Check that the process, that we know to be the Angel, is dead. + + if ( defined $im->{'angel_pid'} ) + { + if ( kill (0, $im->{'angel_pid'}) ) + { + mtr_debug("IM-angel (PID: $im->{angel_pid}) is alive."); + return 1; + } + else + { + mtr_debug("IM-angel (PID: $im->{angel_pid}) is dead."); + return 0; + } + } + else + { + mtr_debug("No PID file for IM-angel."); + return 0; + } +} + +########################################################################### + +sub mtr_im_check_mysqlds_alive($) { + my $im= shift; + + mtr_debug("Checking for IM-guarded mysqld instances..."); + + my $instances = $im->{'instances'}; + + for ( my $idx= 0; $idx < 2; ++$idx ) + { + mtr_debug("Checking mysqld[$idx]..."); + + return 1 + if mtr_im_check_mysqld_alive($instances->[$idx]); + } +} + +########################################################################### + +sub mtr_im_check_mysqld_alive($) { + my $mysqld_instance= shift; + + # Check that the process is dead. + + if ( defined $mysqld_instance->{'pid'} ) + { + if ( kill (0, $mysqld_instance->{'pid'}) ) + { + mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is alive."); + return 1; + } + else + { + mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is dead."); + } + } + else + { + mtr_debug("No PID file for mysqld instance."); + } + + # Check that mysqld does not accept client connections. + + if ( mtr_ping_port($mysqld_instance->{'port'}) ) + { + mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " . + "is accepting connections."); + + mtr_im_errlog("Mysqld is accepting connections on port " . + "$mysqld_instance->{port}, but there is no " . + "process information."); + return 1; + } + else + { + mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " . + "does not accept connections."); + return 0; + } +} + +########################################################################### + +sub mtr_im_cleanup($) { + my $im= shift; + + mtr_im_rm_file($im->{'path_pid'}); + mtr_im_rm_file($im->{'path_sock'}); + + mtr_im_rm_file($im->{'path_angel_pid'}); + + for ( my $idx= 0; $idx < 2; ++$idx ) + { + mtr_im_rm_file($im->{'instances'}->[$idx]->{'path_pid'}); + mtr_im_rm_file($im->{'instances'}->[$idx]->{'path_sock'}); + } +} + +########################################################################### + +sub mtr_im_rm_file($) +{ + my $file_path= shift; + + if ( -f $file_path ) + { + mtr_debug("Removing '$file_path'..."); + + unless ( unlink($file_path) ) + { + mtr_warning("Can not remove '$file_path'.") + } + } + else + { + mtr_debug("File '$file_path' does not exist already."); + } +} + +########################################################################### + +sub mtr_im_errlog($) { + my $msg= shift; + + # Complain in error log so that a warning will be shown. + # + # TODO: unless BUG#20761 is fixed, we will print the warning to stdout, so + # that it can be seen on console and does not produce pushbuild error. + + # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err"; + # + # open (ERRLOG, ">>$errlog") || + # mtr_error("Can not open error log ($errlog)"); + # + # my $ts= localtime(); + # print ERRLOG + # "Warning: [$ts] $msg\n"; + # + # close ERRLOG; + + my $ts= localtime(); + print "Warning: [$ts] $msg\n"; +} + +########################################################################### + +sub mtr_im_kill($) { + my $im= shift; + + # Re-load PIDs. That can be useful because some processes could have been + # restarted. + + mtr_im_load_pids($im); + + # Ignoring SIGCHLD so that all children could rest in peace. + + start_reap_all(); + + # Kill IM-angel first of all. + + if ( defined $im->{'angel_pid'} ) + { + mtr_debug("Killing IM-angel (PID: $im->{angel_pid})..."); + mtr_im_kill_process([ $im->{'angel_pid'} ], 'KILL', 10, 1) + } + else + { + mtr_debug("IM-angel is dead."); + } + + # Re-load PIDs again. + + mtr_im_load_pids($im); + + # Kill IM-main. + + if ( defined $im->{'pid'} ) + { + mtr_debug("Killing IM-main (PID: $im->pid})..."); + mtr_im_kill_process([ $im->{'pid'} ], 'KILL', 10, 1); + } + else + { + mtr_debug("IM-main is dead."); + } + + # Re-load PIDs again. + + mtr_im_load_pids($im); + + # Kill guarded mysqld instances. + + my @mysqld_pids; + + mtr_debug("Collecting PIDs of mysqld instances to kill..."); + + for ( my $idx= 0; $idx < 2; ++$idx ) + { + my $pid= $im->{'instances'}->[$idx]->{'pid'}; + + unless ( defined $pid ) + { + next; + } + + mtr_debug(" - IM-guarded mysqld[$idx] PID: $pid."); + + push (@mysqld_pids, $pid); + } + + if ( scalar @mysqld_pids > 0 ) + { + mtr_debug("Killing IM-guarded mysqld instances..."); + mtr_im_kill_process(\@mysqld_pids, 'KILL', 10, 1); + } + + # That's all. + + stop_reap_all(); +} + +############################################################################## + +sub mtr_im_wait_for_connection($$$) { + my $im= shift; + my $total_attempts= shift; + my $connect_timeout= shift; + + mtr_debug("Waiting for IM on port $im->{port} " . + "to start accepting connections..."); + + for ( my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt ) + { + mtr_debug("Trying to connect to IM ($cur_attempt of $total_attempts)..."); + + if ( mtr_ping_port($im->{'port'}) ) + { + mtr_debug("IM is accepting connections " . + "on port $im->{port}."); + return 1; + } + + mtr_debug("Sleeping $connect_timeout..."); + sleep($connect_timeout); + } + + mtr_debug("IM does not accept connections " . + "on port $im->{port} after " . + ($total_attempts * $connect_timeout) . " seconds."); + + return 0; +} + +############################################################################## + +sub mtr_im_wait_for_mysqld($$$) { + my $mysqld= shift; + my $total_attempts= shift; + my $connect_timeout= shift; + + mtr_debug("Waiting for IM-guarded mysqld on port $mysqld->{port} " . + "to start accepting connections..."); + + for ( my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt ) + { + mtr_debug("Trying to connect to mysqld " . + "($cur_attempt of $total_attempts)..."); + + if ( mtr_ping_port($mysqld->{'port'}) ) + { + mtr_debug("Mysqld is accepting connections " . + "on port $mysqld->{port}."); + return 1; + } + + mtr_debug("Sleeping $connect_timeout..."); + sleep($connect_timeout); + } + + mtr_debug("Mysqld does not accept connections " . + "on port $mysqld->{port} after " . + ($total_attempts * $connect_timeout) . " seconds."); + + return 0; +} + +############################################################################## +# +# Public operations. +# +############################################################################## + +sub mtr_im_start($$) { + my $im = shift; + my $opts = shift; + + mtr_debug("Starting Instance Manager..."); + + my $args; + mtr_init_args(\$args); + mtr_add_arg($args, "--defaults-file=%s", $im->{'defaults_file'}); + + foreach my $opt ( @{$opts} ) + { + mtr_add_arg($args, $opt); + } + + $im->{'pid'} = + mtr_spawn( + $::exe_im, # path to the executable + $args, # cmd-line args + '', # stdin + $im->{'path_log'}, # stdout + $im->{'path_err'}, # stderr + '', # pid file path (not used) + { append_log_file => 1 } # append log files + ); + + unless ( $im->{'pid'} ) + { + mtr_error('Could not start Instance Manager.') + } + + # Instance Manager can be run in daemon mode. In this case, it creates + # several processes and the parent process, created by mtr_spawn(), exits just + # after start. So, we have to obtain Instance Manager PID from the PID file. + + mtr_debug("Waiting for IM to create PID file (" . + "path: '$im->{path_pid}'; " . + "timeout: $im->{start_timeout})..."); + + unless ( sleep_until_file_created($im->{'path_pid'}, + $im->{'start_timeout'}, + -1) ) # real PID is still unknown + { + mtr_debug("IM has not created PID file in $im->{start_timeout} secs."); + mtr_debug("Aborting test suite..."); + + mtr_kill_leftovers(); + + mtr_report("IM has not created PID file in $im->{start_timeout} secs."); + return 0; + } + + $im->{'pid'}= mtr_get_pid_from_file($im->{'path_pid'}); + + mtr_debug("Instance Manager started. PID: $im->{pid}."); + + # Wait until we can connect to IM. + + my $IM_CONNECT_TIMEOUT= 30; + + unless ( mtr_im_wait_for_connection($im, + $IM_CONNECT_TIMEOUT, 1) ) + { + mtr_debug("Can not connect to Instance Manager " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + mtr_debug("Aborting test suite..."); + + mtr_kill_leftovers(); + + mtr_report("Can not connect to Instance Manager " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + return 0; + } + + # Wait for IM to start guarded instances: + # - wait for PID files; + + mtr_debug("Waiting for guarded mysqlds instances to create PID files..."); + + for ( my $idx= 0; $idx < 2; ++$idx ) + { + my $mysqld= $im->{'instances'}->[$idx]; + + if ( exists $mysqld->{'nonguarded'} ) + { + next; + } + + mtr_debug("Waiting for mysqld[$idx] to create PID file (" . + "path: '$mysqld->{path_pid}'; " . + "timeout: $mysqld->{start_timeout})..."); + + unless ( sleep_until_file_created($mysqld->{'path_pid'}, + $mysqld->{'start_timeout'}, + -1) ) # real PID is still unknown + { + mtr_debug("mysqld[$idx] has not created PID file in " . + "$mysqld->{start_timeout} secs."); + mtr_debug("Aborting test suite..."); + + mtr_kill_leftovers(); + + mtr_report("mysqld[$idx] has not created PID file in " . + "$mysqld->{start_timeout} secs."); + return 0; + } + + mtr_debug("PID file for mysqld[$idx] ($mysqld->{path_pid} created."); + } + + # Wait until we can connect to guarded mysqld-instances + # (in other words -- wait for IM to start guarded instances). + + mtr_debug("Waiting for guarded mysqlds to start accepting connections..."); + + for ( my $idx= 0; $idx < 2; ++$idx ) + { + my $mysqld= $im->{'instances'}->[$idx]; + + if ( exists $mysqld->{'nonguarded'} ) + { + next; + } + + mtr_debug("Waiting for mysqld[$idx] to accept connection..."); + + unless ( mtr_im_wait_for_mysqld($mysqld, 30, 1) ) + { + mtr_debug("Can not connect to mysqld[$idx] " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + mtr_debug("Aborting test suite..."); + + mtr_kill_leftovers(); + + mtr_report("Can not connect to mysqld[$idx] " . + "in $IM_CONNECT_TIMEOUT seconds after start."); + return 0; + } + + mtr_debug("mysqld[$idx] started."); + } + + mtr_debug("Instance Manager and its components are up and running."); + + return 1; +} + +############################################################################## + +sub mtr_im_stop($) { + my $im= shift; + + mtr_debug("Stopping Instance Manager..."); + + # Try graceful shutdown. + + mtr_im_terminate($im); + + # Check that all processes died. + + unless ( mtr_im_check_alive($im) ) + { + mtr_debug("Instance Manager has been stopped successfully."); + mtr_im_cleanup($im); + return 1; + } + + # Instance Manager don't want to die. We should kill it. + + mtr_im_errlog("Instance Manager did not shutdown gracefully."); + + mtr_im_kill($im); + + # Check again that all IM-related processes have been killed. + + my $im_is_alive= mtr_im_check_alive($im); + + mtr_im_cleanup($im); + + if ( $im_is_alive ) + { + mtr_debug("Can not kill Instance Manager or its children."); + return 0; + } + + mtr_debug("Instance Manager has been killed successfully."); + return 1; +} + +########################################################################### + +1; diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl index b3da6d97664..8a7fc56269c 100644 --- a/mysql-test/lib/mtr_io.pl +++ b/mysql-test/lib/mtr_io.pl @@ -11,6 +11,8 @@ sub mtr_get_opts_from_file ($); sub mtr_fromfile ($); sub mtr_tofile ($@); sub mtr_tonewfile($@); +sub mtr_lastlinefromfile($); +sub mtr_appendfile_to_file ($$); ############################################################################## # @@ -19,13 +21,39 @@ sub mtr_tonewfile($@); ############################################################################## sub mtr_get_pid_from_file ($) { - my $file= shift; + my $pid_file_path= shift; + my $TOTAL_ATTEMPTS= 30; + my $timeout= 1; - open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!"); - my $pid= ; - chomp($pid); - close FILE; - return $pid; + # We should read from the file until we get correct pid. As it is + # stated in BUG#21884, pid file can be empty at some moment. So, we should + # read it until we get valid data. + + for (my $cur_attempt= 1; $cur_attempt <= $TOTAL_ATTEMPTS; ++$cur_attempt) + { + mtr_debug("Reading pid file '$pid_file_path' " . + "($cur_attempt of $TOTAL_ATTEMPTS)..."); + + open(FILE, '<', $pid_file_path) + or mtr_error("can't open file \"$pid_file_path\": $!"); + + my $pid= ; + + chomp($pid) if defined $pid; + + close FILE; + + return $pid if defined $pid && $pid ne ''; + + mtr_debug("Pid file '$pid_file_path' is empty. " . + "Sleeping $timeout second(s)..."); + + sleep(1); + } + + mtr_error("Pid file '$pid_file_path' is corrupted. " . + "Can not retrieve PID in " . + ($timeout * $TOTAL_ATTEMPTS) . " seconds."); } sub mtr_get_opts_from_file ($) { @@ -113,6 +141,20 @@ sub mtr_fromfile ($) { return $text; } +sub mtr_lastlinefromfile ($) { + my $file= shift; + my $text; + + open(FILE,"<",$file) or mtr_error("can't open file \"$file\": $!"); + while (my $line= ) + { + $text= $line; + } + close FILE; + return $text; +} + + sub mtr_tofile ($@) { my $file= shift; @@ -129,5 +171,17 @@ sub mtr_tonewfile ($@) { close FILE; } +sub mtr_appendfile_to_file ($$) { + my $from_file= shift; + my $to_file= shift; + + open(TOFILE,">>",$to_file) or mtr_error("can't open file \"$to_file\": $!"); + open(FROMFILE,">>",$from_file) + or mtr_error("can't open file \"$from_file\": $!"); + print TOFILE while (); + close FROMFILE; + close TOFILE; +} + 1; diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 08c99e90906..dd9d24ebc8e 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -9,9 +9,10 @@ use strict; sub mtr_full_hostname (); sub mtr_short_hostname (); sub mtr_init_args ($); -sub mtr_add_arg ($$); +sub mtr_add_arg ($$@); sub mtr_path_exists(@); sub mtr_script_exists(@); +sub mtr_file_exists(@); sub mtr_exe_exists(@); sub mtr_copy_dir($$); sub mtr_same_opts($$); @@ -54,7 +55,7 @@ sub mtr_init_args ($) { $$args = []; # Empty list } -sub mtr_add_arg ($$) { +sub mtr_add_arg ($$@) { my $args= shift; my $format= shift; my @fargs = @_; @@ -101,6 +102,14 @@ sub mtr_script_exists (@) { } } +sub mtr_file_exists (@) { + foreach my $path ( @_ ) + { + return $path if -e $path; + } + return ""; +} + sub mtr_exe_exists (@) { my @path= @_; map {$_.= ".exe"} @path if $::glob_win32; @@ -125,18 +134,29 @@ sub mtr_exe_exists (@) { } } + sub mtr_copy_dir($$) { - my $srcdir= shift; - my $dstdir= shift; + my $from_dir= shift; + my $to_dir= shift; + +# mtr_verbose("Copying from $from_dir to $to_dir"); + + mkpath("$to_dir"); + opendir(DIR, "$from_dir") + or mtr_error("Can't find $from_dir$!"); + for(readdir(DIR)) { + next if "$_" eq "." or "$_" eq ".."; + if ( -d "$from_dir/$_" ) + { + mtr_copy_dir("$from_dir/$_", "$to_dir/$_"); + next; + } + copy("$from_dir/$_", "$to_dir/$_"); + } + closedir(DIR); - # Create destination directory - mkpath($dstdir); - find(\&mtr_copy_one_file, $dstdir); } -sub mtr_copy_one_file { - print $File::Find::name, "\n"; -} sub mtr_same_opts ($$) { my $l1= shift; diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 662b70a4fee..5e21248790e 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -4,7 +4,6 @@ # and is part of the translation of the Bourne shell script with the # same name. -#use Carp qw(cluck); use Socket; use Errno; use strict; @@ -14,12 +13,17 @@ use POSIX 'WNOHANG'; sub mtr_run ($$$$$$;$); sub mtr_spawn ($$$$$$;$); -sub mtr_stop_mysqld_servers ($); +sub mtr_check_stop_servers ($); sub mtr_kill_leftovers (); +sub mtr_wait_blocking ($); sub mtr_record_dead_children (); +sub mtr_ndbmgm_start($$); +sub mtr_mysqladmin_start($$$); sub mtr_exit ($); sub sleep_until_file_created ($$$); sub mtr_kill_processes ($); +sub mtr_ping_with_timeout($); +sub mtr_ping_port ($); # static in C sub spawn_impl ($$$$$$$$); @@ -31,7 +35,6 @@ sub spawn_impl ($$$$$$$$); ############################################################################## # This function try to mimic the C version used in "netware/mysql_test_run.c" -# FIXME learn it to handle append mode as well, a "new" flag or a "append" sub mtr_run ($$$$$$;$) { my $path= shift; @@ -112,6 +115,9 @@ sub spawn_impl ($$$$$$$$) { print STDERR "#### ", "-" x 78, "\n"; } + mtr_error("Can't spawn with empty \"path\"") unless defined $path; + + FORK: { my $pid= fork(); @@ -144,17 +150,6 @@ sub spawn_impl ($$$$$$$$) { $SIG{INT}= 'DEFAULT'; # Parent do some stuff, we don't - if ( $::glob_cygwin_shell and $mode eq 'test' ) - { - # Programs started from mysqltest under Cygwin, are to - # execute them within Cygwin. Else simple things in test - # files like - # --system "echo 1 > file" - # will fail. - # FIXME not working :-( -# $ENV{'COMSPEC'}= "$::glob_cygwin_shell -c"; - } - my $log_file_open_mode = '>'; if ($spawn_opts and $spawn_opts->{'append_log_file'}) @@ -164,7 +159,15 @@ sub spawn_impl ($$$$$$$$) { if ( $output ) { - if ( ! open(STDOUT,$log_file_open_mode,$output) ) + if ( $::glob_win32_perl ) + { + # Don't redirect stdout on ActiveState perl since this is + # just another thread in the same process. + # Should be fixed so that the thread that is created with fork + # executes the exe in another process and wait's for it to return. + # In the meanwhile, we get all the output from mysqld's to screen + } + elsif ( ! open(STDOUT,$log_file_open_mode,$output) ) { mtr_child_error("can't redirect STDOUT to \"$output\": $!"); } @@ -216,8 +219,7 @@ sub spawn_parent_impl { { # Simple run of command, we wait for it to return my $ret_pid= waitpid($pid,0); - - if ( $ret_pid <= 0 ) + if ( $ret_pid != $pid ) { mtr_error("$path ($pid) got lost somehow"); } @@ -245,7 +247,6 @@ sub spawn_parent_impl { # Someone terminated, don't know who. Collect # status info first before $? is lost, # but not $exit_value, this is flagged from - # my $timer_name= mtr_timer_timeout($::glob_timers, $ret_pid); if ( $timer_name ) @@ -272,45 +273,22 @@ sub spawn_parent_impl { last; } - # If one of the mysqld processes died, we want to - # mark this, and kill the mysqltest process. + # One of the child processes died, unless this was expected + # mysqltest should be killed and test aborted - foreach my $idx (0..1) - { - if ( $::master->[$idx]->{'pid'} eq $ret_pid ) - { - mtr_debug("child $ret_pid was master[$idx], " . - "exit during mysqltest run"); - $::master->[$idx]->{'pid'}= 0; - last; - } - } - - foreach my $idx (0..2) - { - if ( $::slave->[$idx]->{'pid'} eq $ret_pid ) - { - mtr_debug("child $ret_pid was slave[$idx], " . - "exit during mysqltest run"); - $::slave->[$idx]->{'pid'}= 0; - last; - } - } - - mtr_debug("waitpid() catched exit of unknown child $ret_pid, " . - "exit during mysqltest run"); + check_expected_crash_and_restart($ret_pid); } if ( $ret_pid != $pid ) { # We terminated the waiting because a "mysqld" process died. # Kill the mysqltest process. - + mtr_verbose("Kill mysqltest because another process died"); kill(9,$pid); $ret_pid= waitpid($pid,0); - if ( $ret_pid == -1 ) + if ( $ret_pid != $pid ) { mtr_error("$path ($pid) got lost somehow"); } @@ -351,39 +329,101 @@ sub mtr_process_exit_status { # ############################################################################## -# We just "ping" on the ports, and if we can't do a socket connect -# we assume the server is dead. So we don't *really* know a server -# is dead, we just hope that it after letting the listen port go, -# it is dead enough for us to start a new server. +# Kill all processes(mysqld, ndbd, ndb_mgmd and im) that would conflict with +# this run +# Make sure to remove the PID file, if any. +# kill IM manager first, else it will restart the servers sub mtr_kill_leftovers () { - # First, kill all masters and slaves that would conflict with - # this run. Make sure to remove the PID file, if any. + mtr_report("Killing Possible Leftover Processes"); + mtr_debug("mtr_kill_leftovers(): started."); - my @args; + mkpath("$::opt_vardir/log"); # Needed for mysqladmin log - for ( my $idx; $idx < 2; $idx++ ) + # Stop or kill Instance Manager and all its children. If we failed to do + # that, we can only abort -- there is nothing left to do. + +# mtr_error("Failed to stop Instance Manager.") +# unless mtr_im_stop($::instance_manager); + + # Start shutdown of masters and slaves. Don't touch IM-managed mysqld + # instances -- they should be stopped by mtr_im_stop(). + + mtr_debug("Shutting down mysqld-instances..."); + + my @kill_pids; + my %admin_pids; + + foreach my $srv (@{$::master}, @{$::slave}) { - push(@args,{ - pid => 0, # We don't know the PID - pidfile => $::master->[$idx]->{'path_mypid'}, - sockfile => $::master->[$idx]->{'path_mysock'}, - port => $::master->[$idx]->{'path_myport'}, - }); + mtr_debug(" - mysqld " . + "(pid: $srv->{pid}; " . + "pid file: '$srv->{path_pid}'; " . + "socket: '$srv->{path_sock}'; ". + "port: $srv->{port})"); + + my $pid= mtr_mysqladmin_start($srv, "shutdown", 70); + + # Save the pid of the mysqladmin process + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $srv->{'pid'}, + pidfile => $srv->{'path_pid'}, + sockfile => $srv->{'path_sock'}, + port => $srv->{'port'}, + }); + $srv->{'pid'}= 0; # Assume we are done with it } - for ( my $idx; $idx < 3; $idx++ ) + if ( ! $::opt_skip_ndbcluster ) { - push(@args,{ - pid => 0, # We don't know the PID - pidfile => $::slave->[$idx]->{'path_mypid'}, - sockfile => $::slave->[$idx]->{'path_mysock'}, - port => $::slave->[$idx]->{'path_myport'}, - }); + # Start shutdown of clusters. + mtr_debug("Shutting down cluster..."); + + foreach my $cluster (@{$::clusters}) + { + mtr_debug(" - cluster " . + "(pid: $cluster->{pid}; " . + "pid file: '$cluster->{path_pid})"); + + my $pid= mtr_ndbmgm_start($cluster, "shutdown"); + + # Save the pid of the ndb_mgm process + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + mtr_debug(" - ndbd " . + "(pid: $ndbd->{pid}; " . + "pid file: '$ndbd->{path_pid})"); + + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; # Assume we are done with it + } + } } - mtr_mysqladmin_shutdown(\@args, 20); + # Wait for all the admin processes to complete + mtr_wait_blocking(\%admin_pids); + + # If we trusted "mysqladmin --shutdown_timeout= ..." we could just + # terminate now, but we don't (FIXME should be debugged). + # So we try again to ping and at least wait the same amount of time + # mysqladmin would for all to die. + + mtr_ping_with_timeout(\@kill_pids); # We now have tried to terminate nice. We have waited for the listen # port to be free, but can't really tell if the mysqld process died @@ -401,6 +441,8 @@ sub mtr_kill_leftovers () { # FIXME $path_run_dir or something my $rundir= "$::opt_vardir/run"; + mtr_debug("Processing PID files in directory '$rundir'..."); + if ( -d $rundir ) { opendir(RUNDIR, $rundir) @@ -414,26 +456,32 @@ sub mtr_kill_leftovers () { if ( -f $pidfile ) { + mtr_debug("Processing PID file: '$pidfile'..."); + my $pid= mtr_get_pid_from_file($pidfile); - # Race, could have been removed between I tested with -f - # and the unlink() below, so I better check again with -f - - if ( ! unlink($pidfile) and -f $pidfile ) - { - mtr_error("can't remove $pidfile"); - } + mtr_debug("Got pid: $pid from file '$pidfile'"); if ( $::glob_cygwin_perl or kill(0, $pid) ) { + mtr_debug("There is process with pid $pid -- scheduling for kill."); push(@pids, $pid); # We know (cygwin guess) it exists } + else + { + mtr_debug("There is no process with pid $pid -- skipping."); + } } } closedir(RUNDIR); if ( @pids ) { + mtr_debug("Killing the following processes with PID files: " . + join(' ', @pids) . "..."); + + start_reap_all(); + if ( $::glob_cygwin_perl ) { # We have no (easy) way of knowing the Cygwin controlling @@ -447,8 +495,9 @@ sub mtr_kill_leftovers () { my $retries= 10; # 10 seconds do { + mtr_debug("Sending SIGKILL to pids: " . join(' ', @pids)); kill(9, @pids); - mtr_debug("Sleep 1 second waiting for processes to die"); + mtr_report("Sleep 1 second waiting for processes to die"); sleep(1) # Wait one second } while ( $retries-- and kill(0, @pids) ); @@ -457,56 +506,74 @@ sub mtr_kill_leftovers () { mtr_warning("can't kill process(es) " . join(" ", @pids)); } } + + stop_reap_all(); } } + else + { + mtr_debug("Directory for PID files ($rundir) does not exist."); + } - # We may have failed everything, bug we now check again if we have + # We may have failed everything, but we now check again if we have # the listen ports free to use, and if they are free, just go for it. - foreach my $srv ( @args ) + mtr_debug("Checking known mysqld servers..."); + + foreach my $srv ( @kill_pids ) { - if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) + if ( defined $srv->{'port'} and mtr_ping_port($srv->{'port'}) ) { - mtr_warning("can't kill old mysqld holding port $srv->{'port'}"); + mtr_warning("can't kill old process holding port $srv->{'port'}"); } } + + mtr_debug("mtr_kill_leftovers(): finished."); } -############################################################################## -# -# Shut down mysqld servers we have started from this run of this script -# -############################################################################## - -# To speed things we kill servers in parallel. The argument is a list -# of 'ports', 'pids', 'pidfiles' and 'socketfiles'. +# Check that all processes in list are killed +# The argument is a list of 'ports', 'pids', 'pidfiles' and 'socketfiles' +# for which shutdown has been started. Make sure they all get killed +# in one way or the other. +# # FIXME On Cygwin, and maybe some other platforms, $srv->{'pid'} and -# $srv->{'pidfile'} will not be the same PID. We need to try to kill +# the pid in $srv->{'pidfile'} will not be the same PID. We need to try to kill # both I think. -sub mtr_stop_mysqld_servers ($) { +sub mtr_check_stop_servers ($) { my $spec= shift; - # ---------------------------------------------------------------------- - # First try nice normal shutdown using 'mysqladmin' - # ---------------------------------------------------------------------- + # Return if no processes are defined + return if ! @$spec; - # Shutdown time must be high as slave may be in reconnect - mtr_mysqladmin_shutdown($spec, 70); + #mtr_report("mtr_check_stop_servers"); + + mtr_ping_with_timeout(\@$spec); # ---------------------------------------------------------------------- # We loop with waitpid() nonblocking to see how many of the ones we - # are to kill, actually got killed by mtr_mysqladmin_shutdown(). - # Note that we don't rely on this, the mysqld server might have stop + # are to kill, actually got killed by mysqladmin or ndb_mgm + # + # Note that we don't rely on this, the mysqld server might have stopped # listening to the port, but still be alive. But it is a start. # ---------------------------------------------------------------------- foreach my $srv ( @$spec ) { - if ( $srv->{'pid'} and (waitpid($srv->{'pid'},&WNOHANG) == $srv->{'pid'}) ) + my $ret_pid; + if ( $srv->{'pid'} ) { - $srv->{'pid'}= 0; + $ret_pid= waitpid($srv->{'pid'},&WNOHANG); + if ($ret_pid == $srv->{'pid'}) + { + mtr_verbose("Caught exit of process $ret_pid"); + $srv->{'pid'}= 0; + } + else + { + # mtr_warning("caught exit of unknown child $ret_pid"); + } } } @@ -540,13 +607,12 @@ sub mtr_stop_mysqld_servers ($) { } # ---------------------------------------------------------------------- - # If the processes where started from this script, and we had no PIDS + # If all the processes in list already have been killed, # then we don't have to do anything. # ---------------------------------------------------------------------- if ( ! keys %mysqld_pids ) { - # cluck "This is how we got here!"; return; } @@ -595,141 +661,290 @@ sub mtr_stop_mysqld_servers ($) { foreach my $file ($srv->{'pidfile'}, $srv->{'sockfile'}) { # Know it is dead so should be no race, careful anyway - if ( -f $file and ! unlink($file) and -f $file ) + if ( defined $file and -f $file and ! unlink($file) and -f $file ) { $errors++; mtr_warning("couldn't delete $file"); } } + $srv->{'pid'}= 0; } } } if ( $errors ) { - # We are in trouble, just die.... - mtr_error("we could not kill or clean up all processes"); + # There where errors killing processes + # do one last attempt to ping the servers + # and if they can't be pinged, assume they are dead + if ( ! mtr_ping_with_timeout( \@$spec ) ) + { + mtr_error("we could not kill or clean up all processes"); + } + else + { + mtr_verbose("All ports were free, continuing"); + } } } # FIXME We just assume they are all dead, for Cygwin we are not # really sure - + +} + +# Wait for all the process in the list to terminate +sub mtr_wait_blocking($) { + my $admin_pids= shift; + + + # Return if no processes defined + return if ! %$admin_pids; + + mtr_verbose("mtr_wait_blocking"); + + # Wait for all the started processes to exit + # As mysqladmin is such a simple program, we trust it to terminate itself. + # I.e. we wait blocking, and wait for them all before we go on. + foreach my $pid (keys %{$admin_pids}) + { + my $ret_pid= waitpid($pid,0); + + } +} + +# Start "mysqladmin shutdown" for a specific mysqld +sub mtr_mysqladmin_start($$$) { + my $srv= shift; + my $command= shift; + my $adm_shutdown_tmo= shift; + + my $args; + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--user=%s", $::opt_user); + mtr_add_arg($args, "--password="); + mtr_add_arg($args, "--silent"); + if ( -e $srv->{'path_sock'} ) + { + mtr_add_arg($args, "--socket=%s", $srv->{'path_sock'}); + } + if ( $srv->{'port'} ) + { + mtr_add_arg($args, "--port=%s", $srv->{'port'}); + } + if ( $srv->{'port'} and ! -e $srv->{'path_sock'} ) + { + mtr_add_arg($args, "--protocol=tcp"); # Needed if no --socket + } + mtr_add_arg($args, "--connect_timeout=5"); + + # Shutdown time must be high as slave may be in reconnect + mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo"); + mtr_add_arg($args, "$command"); + my $path_mysqladmin_log= "$::opt_vardir/log/mysqladmin.log"; + my $pid= mtr_spawn($::exe_mysqladmin, $args, + "", $path_mysqladmin_log, $path_mysqladmin_log, "", + { append_log_file => 1 }); + mtr_verbose("mtr_mysqladmin_start, pid: $pid"); + return $pid; + +} + +# Start "ndb_mgm shutdown" for a specific cluster, it will +# shutdown all data nodes and leave the ndb_mgmd running +sub mtr_ndbmgm_start($$) { + my $cluster= shift; + my $command= shift; + + my $args; + + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--try-reconnect=1"); + mtr_add_arg($args, "--ndb_connectstring=%s", $cluster->{'connect_string'}); + mtr_add_arg($args, "-e"); + mtr_add_arg($args, "$command"); + + my $pid= mtr_spawn($::exe_ndb_mgm, $args, + "", "/dev/null", "/dev/null", "", + {}); + mtr_verbose("mtr_ndbmgm_start, pid: $pid"); + return $pid; + } -############################################################################## -# -# Shut down mysqld servers using "mysqladmin ... shutdown". -# To speed this up, we start them in parallel and use waitpid() to -# catch their termination. Note that this doesn't say the servers -# are terminated, just that 'mysqladmin' is terminated. -# -# Note that mysqladmin will ask the server about what PID file it uses, -# and mysqladmin will wait for it to be removed before it terminates -# (unless passes timeout). -# -# This function will take at most about 20 seconds, and we still are not -# sure we killed them all. If none is responding to ping, we return 1, -# else we return 0. -# -############################################################################## - -sub mtr_mysqladmin_shutdown { +# Ping all servers in list, exit when none of them answers +# or when timeout has passed +sub mtr_ping_with_timeout($) { my $spec= shift; - my $adm_shutdown_tmo= shift; - - my %mysql_admin_pids; - my @to_kill_specs; - - foreach my $srv ( @$spec ) - { - if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) - { - push(@to_kill_specs, $srv); - } - } - - - foreach my $srv ( @to_kill_specs ) - { - # FIXME wrong log..... - # FIXME, stderr..... - # Shutdown time must be high as slave may be in reconnect - my $args; - - mtr_init_args(\$args); - - mtr_add_arg($args, "--no-defaults"); - mtr_add_arg($args, "--user=%s", $::opt_user); - mtr_add_arg($args, "--password="); - if ( -e $srv->{'sockfile'} ) - { - mtr_add_arg($args, "--socket=%s", $srv->{'sockfile'}); - } - if ( $srv->{'port'} ) - { - mtr_add_arg($args, "--port=%s", $srv->{'port'}); - } - if ( $srv->{'port'} and ! -e $srv->{'sockfile'} ) - { - mtr_add_arg($args, "--protocol=tcp"); # Needed if no --socket - } - mtr_add_arg($args, "--connect_timeout=5"); - mtr_add_arg($args, "--shutdown_timeout=$adm_shutdown_tmo"); - mtr_add_arg($args, "shutdown"); - # We don't wait for termination of mysqladmin - my $pid= mtr_spawn($::exe_mysqladmin, $args, - "", $::path_manager_log, $::path_manager_log, "", - { append_log_file => 1 }); - $mysql_admin_pids{$pid}= 1; - } - - # As mysqladmin is such a simple program, we trust it to terminate. - # I.e. we wait blocking, and wait wait for them all before we go on. - while (keys %mysql_admin_pids) - { - foreach my $pid (keys %mysql_admin_pids) - { - if ( waitpid($pid,0) > 0 ) - { - delete $mysql_admin_pids{$pid}; - } - } - } - - # If we trusted "mysqladmin --shutdown_timeout= ..." we could just - # terminate now, but we don't (FIXME should be debugged). - # So we try again to ping and at least wait the same amount of time - # mysqladmin would for all to die. - - my $timeout= 20; # 20 seconds max + my $timeout= 200; # 20 seconds max my $res= 1; # If we just fall through, we are done # in the sense that the servers don't # listen to their ports any longer + + mtr_debug("Waiting for mysqld servers to stop..."); + TIME: while ( $timeout-- ) { - foreach my $srv ( @to_kill_specs ) + foreach my $srv ( @$spec ) { $res= 1; # We are optimistic - if ( mtr_ping_mysqld_server($srv->{'port'}, $srv->{'sockfile'}) ) + if ( $srv->{'pid'} and defined $srv->{'port'} ) { - mtr_debug("Sleep 1 second waiting for processes to stop using port"); - sleep(1); # One second - $res= 0; - next TIME; + if ( mtr_ping_port($srv->{'port'}) ) + { + mtr_verbose("waiting for process $srv->{'pid'} to stop ". + "using port $srv->{'port'}"); + + # Millisceond sleep emulated with select + select(undef, undef, undef, (0.1)); + $res= 0; + next TIME; + } + else + { + # Process was not using port + } } } last; # If we got here, we are done } - $timeout or mtr_debug("At least one server is still listening to its port"); - - sleep(5) if $::glob_win32; # FIXME next startup fails if no sleep + if ($res) + { + mtr_debug("mtr_ping_with_timeout(): All mysqld instances are down."); + } + else + { + mtr_report("mtr_ping_with_timeout(): At least one server is alive."); + } return $res; } + +# +# Loop through our list of processes and look for and entry +# with the provided pid +# Set the pid of that process to 0 if found +# +sub mark_process_dead($) +{ + my $ret_pid= shift; + + foreach my $mysqld (@{$::master}, @{$::slave}) + { + if ( $mysqld->{'pid'} eq $ret_pid ) + { + mtr_verbose("$mysqld->{'type'} $mysqld->{'idx'} exited, pid: $ret_pid"); + $mysqld->{'pid'}= 0; + return; + } + } + + foreach my $cluster (@{$::clusters}) + { + if ( $cluster->{'pid'} eq $ret_pid ) + { + mtr_verbose("$cluster->{'name'} cluster ndb_mgmd exited, pid: $ret_pid"); + $cluster->{'pid'}= 0; + return; + } + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + if ( $ndbd->{'pid'} eq $ret_pid ) + { + mtr_verbose("$cluster->{'name'} cluster ndbd exited, pid: $ret_pid"); + $ndbd->{'pid'}= 0; + return; + } + } + } + mtr_warning("mark_process_dead couldn't find an entry for pid: $ret_pid"); + +} + +# +# Loop through our list of processes and look for and entry +# with the provided pid, if found check for the file indicating +# expected crash and restart it. +# +sub check_expected_crash_and_restart($) +{ + my $ret_pid= shift; + + foreach my $mysqld (@{$::master}, @{$::slave}) + { + if ( $mysqld->{'pid'} eq $ret_pid ) + { + mtr_verbose("$mysqld->{'type'} $mysqld->{'idx'} exited, pid: $ret_pid"); + $mysqld->{'pid'}= 0; + + # Check if crash expected and restart if it was + my $expect_file= "$::opt_vardir/tmp/" . "$mysqld->{'type'}" . + "$mysqld->{'idx'}" . ".expect"; + if ( -f $expect_file ) + { + mtr_verbose("Crash was expected, file $expect_file exists"); + mysqld_start($mysqld, $mysqld->{'start_opts'}, + $mysqld->{'start_slave_master_info'}); + unlink($expect_file); + } + + return; + } + } + + foreach my $cluster (@{$::clusters}) + { + if ( $cluster->{'pid'} eq $ret_pid ) + { + mtr_verbose("$cluster->{'name'} cluster ndb_mgmd exited, pid: $ret_pid"); + $cluster->{'pid'}= 0; + + # Check if crash expected and restart if it was + my $expect_file= "$::opt_vardir/tmp/ndb_mgmd_" . "$cluster->{'type'}" . + ".expect"; + if ( -f $expect_file ) + { + mtr_verbose("Crash was expected, file $expect_file exists"); + ndbmgmd_start($cluster); + unlink($expect_file); + } + return; + } + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + if ( $ndbd->{'pid'} eq $ret_pid ) + { + mtr_verbose("$cluster->{'name'} cluster ndbd exited, pid: $ret_pid"); + $ndbd->{'pid'}= 0; + + # Check if crash expected and restart if it was + my $expect_file= "$::opt_vardir/tmp/ndbd_" . "$cluster->{'type'}" . + "$ndbd->{'idx'}" . ".expect"; + if ( -f $expect_file ) + { + mtr_verbose("Crash was expected, file $expect_file exists"); + ndbd_start($cluster, $ndbd->{'idx'}, + $ndbd->{'start_extra_args'}); + unlink($expect_file); + } + return; + } + } + } + mtr_warning("check_expected_crash_and_restart couldn't find an entry for pid: $ret_pid"); + +} + ############################################################################## # # The operating system will keep information about dead children, @@ -740,32 +955,18 @@ sub mtr_mysqladmin_shutdown { sub mtr_record_dead_children () { + my $process_died= 0; my $ret_pid; - # FIXME the man page says to wait for -1 to terminate, - # but on OS X we get '0' all the time... - while ( ($ret_pid= waitpid(-1,&WNOHANG)) > 0 ) + # Wait without blockinng to see if any processes had died + # -1 or 0 means there are no more procesess to wait for + while ( ($ret_pid= waitpid(-1,&WNOHANG)) != 0 and $ret_pid != -1) { - mtr_debug("waitpid() catched exit of child $ret_pid"); - foreach my $idx (0..1) - { - if ( $::master->[$idx]->{'pid'} eq $ret_pid ) - { - mtr_debug("child $ret_pid was master[$idx]"); - $::master->[$idx]->{'pid'}= 0; - } - } - - foreach my $idx (0..2) - { - if ( $::slave->[$idx]->{'pid'} eq $ret_pid ) - { - mtr_debug("child $ret_pid was slave[$idx]"); - $::slave->[$idx]->{'pid'}= 0; - last; - } - } + mtr_warning("mtr_record_dead_children: $ret_pid"); + mark_process_dead($ret_pid); + $process_died= 1; } + return $process_died; } sub start_reap_all { @@ -777,16 +978,24 @@ sub start_reap_all { # here. If a process terminated before setting $SIG{CHLD} (but after # any attempt to waitpid() it), it will still be a zombie. So we # have to handle any such process here. - while(waitpid(-1, &WNOHANG) > 0) { }; + my $pid; + while(($pid= waitpid(-1, &WNOHANG)) != 0 and $pid != -1) + { + mtr_warning("start_reap_all pid: $pid"); + mark_process_dead($pid); + }; } sub stop_reap_all { $SIG{CHLD}= 'DEFAULT'; } -sub mtr_ping_mysqld_server () { + +sub mtr_ping_port ($) { my $port= shift; + mtr_verbose("mtr_ping_port: $port"); + my $remote= "localhost"; my $iaddr= inet_aton($remote); if ( ! $iaddr ) @@ -799,13 +1008,18 @@ sub mtr_ping_mysqld_server () { { mtr_error("can't create socket: $!"); } + + mtr_debug("Pinging server (port: $port)..."); + if ( connect(SOCK, $paddr) ) { close(SOCK); # FIXME check error? + mtr_verbose("USED"); return 1; } else { + mtr_verbose("FREE"); return 0; } } @@ -822,30 +1036,36 @@ sub sleep_until_file_created ($$$) { my $pidfile= shift; my $timeout= shift; my $pid= shift; + my $sleeptime= 100; # Milliseconds + my $loops= ($timeout * 1000) / $sleeptime; - for ( my $loop= 1; $loop <= $timeout; $loop++ ) + for ( my $loop= 1; $loop <= $loops; $loop++ ) { if ( -r $pidfile ) { return $pid; } - # Check if it died after the fork() was successful - if ( waitpid($pid,&WNOHANG) == $pid ) + # Check if it died after the fork() was successful + if ( $pid != 0 && waitpid($pid,&WNOHANG) == $pid ) { + mtr_warning("Process $pid died"); return 0; } - mtr_debug("Sleep 1 second waiting for creation of $pidfile"); + mtr_debug("Sleep $sleeptime milliseconds waiting for $pidfile"); - if ( $loop % 60 == 0 ) + # Print extra message every 60 seconds + my $seconds= ($loop * $sleeptime) / 1000; + if ( $seconds > 1 and int($seconds) % 60 == 0 ) { - my $left= $timeout - $loop; - mtr_warning("Waited $loop seconds for $pidfile to be created, " . + my $left= $timeout - $seconds; + mtr_warning("Waited $seconds seconds for $pidfile to be created, " . "still waiting for $left seconds..."); } - sleep(1); + # Millisceond sleep emulated with select + select(undef, undef, undef, ($sleeptime/1000)); } return 0; @@ -855,18 +1075,18 @@ sub sleep_until_file_created ($$$) { sub mtr_kill_processes ($) { my $pids = shift; - foreach my $sig (15,9) + mtr_verbose("mtr_kill_processes " . join(" ", @$pids)); + + foreach my $pid (@$pids) { - my $retries= 20; # FIXME 20 seconds, this is silly! - kill($sig, @{$pids}); - while ( $retries-- and kill(0, @{$pids}) ) + foreach my $sig (15, 9) { - mtr_debug("Sleep 1 second waiting for processes to die"); - sleep(1) # Wait one second + last if mtr_im_kill_process([ $pid ], $sig, 10, 1); } } } + ############################################################################## # # When we exit, we kill off all children @@ -876,7 +1096,7 @@ sub mtr_kill_processes ($) { # FIXME something is wrong, we sometimes terminate with "Hangup" written # to tty, and no STDERR output telling us why. -# FIXME for some readon, setting HUP to 'IGNORE' will cause exit() to +# FIXME for some reason, setting HUP to 'IGNORE' will cause exit() to # write out "Hangup", and maybe loose some output. We insert a sleep... sub mtr_exit ($) { @@ -884,9 +1104,18 @@ sub mtr_exit ($) { # cluck("Called mtr_exit()"); mtr_timer_stop_all($::glob_timers); local $SIG{HUP} = 'IGNORE'; - kill('HUP', -$$); - sleep 2; + # ToDo: Signalling -$$ will only work if we are the process group + # leader (in fact on QNX it will signal our session group leader, + # which might be Do-compile or Pushbuild, causing tests to be + # aborted). So we only do it if we are the group leader. We might + # set ourselves as the group leader at startup (with + # POSIX::setpgrp(0,0)), but then care must be needed to always do + # proper child process cleanup. + kill('HUP', -$$) if !$::glob_win32_perl and $$ == getpgrp(); + exit($code); } +########################################################################### + 1; diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 515988ee5c7..6e3796133f2 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -10,6 +10,7 @@ sub mtr_report_test_name($); sub mtr_report_test_passed($); sub mtr_report_test_failed($); sub mtr_report_test_skipped($); +sub mtr_report_test_not_skipped_though_disabled($); sub mtr_show_failed_diff ($); sub mtr_report_stats ($); @@ -21,6 +22,7 @@ sub mtr_warning (@); sub mtr_error (@); sub mtr_child_error (@); sub mtr_debug (@); +sub mtr_verbose (@); ############################################################################## @@ -36,6 +38,7 @@ sub mtr_show_failed_diff ($) { my $reject_file= "r/$tname.reject"; my $result_file= "r/$tname.result"; + my $log_file= "r/$tname.log"; my $eval_file= "r/$tname.eval"; if ( $::opt_suite ne "main" ) @@ -43,10 +46,11 @@ sub mtr_show_failed_diff ($) { $reject_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$reject_file"; $result_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$result_file"; $eval_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$eval_file"; + $log_file= "$::glob_mysql_test_dir/suite/$::opt_suite/$log_file"; } if ( -f $eval_file ) - { + { $result_file= $eval_file; } elsif ( $::opt_result_ext and @@ -70,6 +74,12 @@ sub mtr_show_failed_diff ($) { print "http://www.mysql.com/doc/en/Reporting_mysqltest_bugs.html\n"; print "to find the reason to this problem and how to report this.\n\n"; } + + if ( -f $log_file ) + { + print "Result from queries before failure can be found in $log_file\n"; + # FIXME Maybe a tail -f -n 10 $log_file here + } } sub mtr_report_test_name ($) { @@ -88,7 +98,24 @@ sub mtr_report_test_skipped ($) { } else { - print "[ skipped ]\n"; + print "[ skipped ] $tinfo->{'comment'}\n"; + } +} + +sub mtr_report_tests_not_skipped_though_disabled ($) { + my $tests= shift; + + if ( $::opt_enable_disabled ) + { + my @disabled_tests= grep {$_->{'dont_skip_though_disabled'}} @$tests; + if ( @disabled_tests ) + { + print "\nTest(s) which will be run though they are marked as disabled:\n"; + foreach my $tinfo ( sort {$a->{'name'} cmp $b->{'name'}} @disabled_tests ) + { + printf " %-20s : %s\n", $tinfo->{'name'}, $tinfo->{'comment'}; + } + } } } @@ -99,7 +126,7 @@ sub mtr_report_test_passed ($) { if ( $::opt_timer and -f "$::opt_vardir/log/timer" ) { $timer= mtr_fromfile("$::opt_vardir/log/timer"); - $::glob_tot_real_time += $timer; + $::glob_tot_real_time += ($timer/1000); $timer= sprintf "%12s", $timer; } $tinfo->{'result'}= 'MTR_RES_PASSED'; @@ -114,6 +141,11 @@ sub mtr_report_test_failed ($) { { print "[ fail ] timeout\n"; } + elsif ( $tinfo->{'ndb_test'} and $::cluster->[0]->{'installed_ok'} eq "NO") + { + print "[ fail ] ndbcluster start failure\n"; + return; + } else { print "[ fail ]\n"; @@ -144,6 +176,8 @@ sub mtr_report_stats ($) { my $tot_passed= 0; my $tot_failed= 0; my $tot_tests= 0; + my $tot_restarts= 0; + my $found_problems= 0; # Some warnings are errors... foreach my $tinfo (@$tests) { @@ -161,6 +195,10 @@ sub mtr_report_stats ($) { $tot_tests++; $tot_failed++; } + if ( $tinfo->{'restarted'} ) + { + $tot_restarts++; + } } # ---------------------------------------------------------------------- @@ -183,41 +221,69 @@ sub mtr_report_stats ($) { "the documentation at\n", "http://www.mysql.com/doc/en/MySQL_test_suite.html\n"; } + print + "The servers were restarted $tot_restarts times\n"; + + if ( $::opt_timer ) + { + print + "Spent $::glob_tot_real_time seconds actually executing testcases\n" + } # ---------------------------------------------------------------------- + # If a debug run, there might be interesting information inside + # the "var/log/*.err" files. We save this info in "var/log/warnings" # ---------------------------------------------------------------------- if ( ! $::glob_use_running_server ) { + # Save and report if there was any fatal warnings/errors in err logs - # Report if there was any fatal warnings/errors in the log files - # - unlink("$::opt_vardir/log/warnings"); - unlink("$::opt_vardir/log/warnings.tmp"); - # Remove some non fatal warnings from the log files + my $warnlog= "$::opt_vardir/log/warnings"; -# FIXME what is going on ????? ;-) -# sed -e 's!Warning: Table:.* on delete!!g' -e 's!Warning: Setting lower_case_table_names=2!!g' -e 's!Warning: One can only use the --user.*root!!g' \ -# var/log/*.err \ -# | sed -e 's!Warning: Table:.* on rename!!g' \ -# > var/log/warnings.tmp; -# -# found_error=0; -# # Find errors -# for i in "^Warning:" "^Error:" "^==.* at 0x" -# do -# if ( $GREP "$i" var/log/warnings.tmp >> var/log/warnings ) -# { -# found_error=1 -# } -# done -# unlink("$::opt_vardir/log/warnings.tmp"); -# if ( $found_error= "1" ) -# { -# print "WARNING: Got errors/warnings while running tests. Please examine\n" -# print "$::opt_vardir/log/warnings for details.\n" -# } -# } + unless ( open(WARN, ">$warnlog") ) + { + mtr_warning("can't write to the file \"$warnlog\": $!"); + } + else + { + # We report different types of problems in order + foreach my $pattern ( "^Warning:", "^Error:", "^==.* at 0x", + "InnoDB: Warning", "missing DBUG_RETURN", + "mysqld: Warning", + "Attempting backtrace", "Assertion .* failed" ) + { + foreach my $errlog ( sort glob("$::opt_vardir/log/*.err") ) + { + unless ( open(ERR, $errlog) ) + { + mtr_warning("can't read $errlog"); + next; + } + while ( ) + { + # Skip some non fatal warnings from the log files + if ( /Warning:\s+Table:.* on (delete|rename)/ or + /Warning:\s+Setting lower_case_table_names=2/ or + /Warning:\s+One can only use the --user.*root/ or + /InnoDB: Warning: we did not need to do crash recovery/) + { + next; # Skip these lines + } + if ( /$pattern/ ) + { + $found_problems= 1; + print WARN $_; + } + } + } + } + if ( $found_problems ) + { + mtr_warning("Got errors/warnings while running tests, please examine", + "\"$warnlog\" for details."); + } + } } print "\n"; @@ -235,6 +301,9 @@ sub mtr_report_stats ($) { } } print "\n"; + } + if ( $tot_failed != 0 || $found_problems) + { mtr_error("there where failing test cases"); } } @@ -298,5 +367,11 @@ sub mtr_debug (@) { print STDERR "####: ",join(" ", @_),"\n"; } } +sub mtr_verbose (@) { + if ( $::opt_verbose ) + { + print STDERR "> ",join(" ", @_),"\n"; + } +} 1; diff --git a/mysql-test/lib/mtr_stress.pl b/mysql-test/lib/mtr_stress.pl new file mode 100644 index 00000000000..a7d4b68b69d --- /dev/null +++ b/mysql-test/lib/mtr_stress.pl @@ -0,0 +1,178 @@ +# -*- cperl -*- + +# This is a library file used by the Perl version of mysql-test-run, +# and is part of the translation of the Bourne shell script with the +# same name. + +use strict; +use File::Spec; + +# These are not to be prefixed with "mtr_" + +sub run_stress_test (); + +############################################################################## +# +# Run tests in the stress mode +# +############################################################################## + +sub run_stress_test () +{ + + my $args; + my $stress_suitedir; + + mtr_report("Starting stress testing\n"); + + if ( ! $::glob_use_embedded_server ) + { + if ( ! mysqld_start($::master->[0],[],[]) ) + { + mtr_error("Can't start the mysqld server"); + } + } + + my $stress_basedir=File::Spec->catdir($::opt_vardir, "stress"); + + #Clean up stress dir + if ( -d $stress_basedir ) + { + rmtree($stress_basedir); + } + mkpath($stress_basedir); + + if ($::opt_stress_suite ne 'main' && $::opt_stress_suite ne 'default' ) + { + $stress_suitedir=File::Spec->catdir($::glob_mysql_test_dir, "suite", + $::opt_stress_suite); + } + else + { + $stress_suitedir=$::glob_mysql_test_dir; + } + + if ( -d $stress_suitedir ) + { + #$stress_suite_t_dir=File::Spec->catdir($stress_suitedir, "t"); + #$stress_suite_r_dir=File::Spec->catdir($stress_suitedir, "r"); + #FIXME: check dirs above for existence to ensure that test suite + # contains tests and results dirs + } + else + { + mtr_error("Specified test suite $::opt_stress_suite doesn't exist"); + } + + if ( @::opt_cases ) + { + $::opt_stress_test_file=File::Spec->catfile($stress_basedir, "stress_tests.txt"); + open(STRESS_FILE, ">$::opt_stress_test_file"); + print STRESS_FILE join("\n",@::opt_cases),"\n"; + close(STRESS_FILE); + } + elsif ( $::opt_stress_test_file ) + { + $::opt_stress_test_file=File::Spec->catfile($stress_suitedir, + $::opt_stress_test_file); + if ( ! -f $::opt_stress_test_file ) + { + mtr_error("Specified file $::opt_stress_test_file with list of tests does not exist\n", + "Please ensure that file exists and has proper permissions"); + } + } + else + { + $::opt_stress_test_file=File::Spec->catfile($stress_suitedir, + "stress_tests.txt"); + if ( ! -f $::opt_stress_test_file ) + { + mtr_error("Default file $::opt_stress_test_file with list of tests does not exist\n", + "Please use --stress-test-file option to specify custom one or you can\n", + "just specify name of test for testing as last argument in command line"); + + } + } + + if ( $::opt_stress_init_file ) + { + $::opt_stress_init_file=File::Spec->catfile($stress_suitedir, + $::opt_stress_init_file); + if ( ! -f $::opt_stress_init_file ) + { + mtr_error("Specified file $::opt_stress_init_file with list of tests does not exist\n", + "Please ensure that file exists and has proper permissions"); + } + } + else + { + $::opt_stress_init_file=File::Spec->catfile($stress_suitedir, + "stress_init.txt"); + if ( ! -f $::opt_stress_init_file ) + { + $::opt_stress_init_file=''; + } + } + + if ( $::opt_stress_mode ne 'random' && $::opt_stress_mode ne 'seq' ) + { + mtr_error("You specified wrong mode $::opt_stress_mode for stress test\n", + "Correct values are 'random' or 'seq'"); + } + + mtr_init_args(\$args); + + mtr_add_arg($args, "--server-socket=%s", $::master->[0]->{'path_mysock'}); + mtr_add_arg($args, "--server-user=%s", $::opt_user); + mtr_add_arg($args, "--server-database=%s", "test"); + mtr_add_arg($args, "--stress-suite-basedir=%s", $::glob_mysql_test_dir); + mtr_add_arg($args, "--suite=%s", $::opt_stress_suite); + mtr_add_arg($args, "--stress-tests-file=%s", $::opt_stress_test_file); + mtr_add_arg($args, "--stress-basedir=%s", $stress_basedir); + mtr_add_arg($args, "--server-logs-dir=%s", $stress_basedir); + mtr_add_arg($args, "--stress-mode=%s", $::opt_stress_mode); + mtr_add_arg($args, "--mysqltest=%s", $::exe_mysqltest); + mtr_add_arg($args, "--threads=%s", $::opt_stress_threads); + mtr_add_arg($args, "--verbose"); + mtr_add_arg($args, "--cleanup"); + mtr_add_arg($args, "--log-error-details"); + mtr_add_arg($args, "--abort-on-error"); + + if ( $::opt_stress_init_file ) + { + mtr_add_arg($args, "--stress-init-file=%", $::opt_stress_init_file); + } + + if ( !$::opt_stress_loop_count && !$::opt_stress_test_count && + !$::opt_stress_test_duration ) + { + #Limit stress testing with 20 loops in case when any limit parameter + #was specified + $::opt_stress_test_count=20; + } + + if ( $::opt_stress_loop_count ) + { + mtr_add_arg($args, "--loop-count=%s", $::opt_stress_loop_count); + } + + if ( $::opt_stress_test_count ) + { + mtr_add_arg($args, "--test-count=%s", $::opt_stress_test_count); + } + + if ( $::opt_stress_test_duration ) + { + mtr_add_arg($args, "--test-duration=%s", $::opt_stress_test_duration); + } + + #Run stress test + mtr_run("$::glob_mysql_test_dir/mysql-stress-test.pl", $args, "", "", "", ""); + + if ( ! $::glob_use_embedded_server ) + { + stop_masters(); + } +} + +1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index d1e049ff883..39c116a3fcb 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -66,10 +66,6 @@ # "http://www.plover.com/~mjd/perl/Trace/" and run this script like # "perl -d:Trace mysql-test-run.pl" # -# FIXME Save a PID file from this code as well, to record the process -# id we think it has. In Cygwin, a fork creates one Cygwin process, -# and then the real Win32 process. Cygwin Perl can only kill Cygwin -# processes. And "mysqld --bootstrap ..." doesn't save a PID file. $Devel::Trace::TRACE= 0; # Don't trace boring init stuff @@ -80,14 +76,19 @@ use File::Copy; use Cwd; use Getopt::Long; use Sys::Hostname; -#use Carp; use IO::Socket; use IO::Socket::INET; use Data::Dumper; use strict; #use diagnostics; +our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl +our $glob_cygwin_perl= ($^O eq "cygwin"); # Cygwin Perl +our $glob_win32= ($glob_win32_perl or $glob_cygwin_perl); +our $glob_netware= ($^O eq "NetWare"); # NetWare + require "lib/mtr_cases.pl"; +require "lib/mtr_im.pl"; require "lib/mtr_process.pl"; require "lib/mtr_timer.pl"; require "lib/mtr_io.pl"; @@ -97,6 +98,7 @@ require "lib/mtr_report.pl"; require "lib/mtr_diff.pl"; require "lib/mtr_match.pl"; require "lib/mtr_misc.pl"; +require "lib/mtr_stress.pl"; $Devel::Trace::TRACE= 1; @@ -128,11 +130,7 @@ our @mysqld_src_dirs= # structs. We let each struct be a separate hash. # Misc global variables - -our $glob_win32= 0; # OS and native Win32 executables -our $glob_win32_perl= 0; # ActiveState Win32 Perl -our $glob_cygwin_perl= 0; # Cygwin Perl -our $glob_cygwin_shell= undef; +our $mysql_version_id; our $glob_mysql_test_dir= undef; our $glob_mysql_bench_dir= undef; our $glob_hostname= undef; @@ -140,32 +138,30 @@ our $glob_scriptname= undef; our $glob_timers= undef; our $glob_use_running_server= 0; our $glob_use_running_ndbcluster= 0; +our $glob_use_running_ndbcluster_slave= 0; our $glob_use_embedded_server= 0; our @glob_test_mode; our $glob_basedir; -# The total result - our $path_charsetsdir; our $path_client_bindir; our $path_language; our $path_timefile; -our $path_manager_log; # Used by mysqldadmin -our $path_slave_load_tmpdir; # What is this?! +our $path_snapshot; our $path_mysqltest_log; +our $path_current_test_log; our $path_my_basedir; + our $opt_vardir; # A path but set directly on cmd line +our $path_vardir_trace; # unix formatted opt_vardir for trace files our $opt_tmpdir; # A path but set directly on cmd line our $opt_usage; our $opt_suite; -our $opt_netware; - our $opt_script_debug= 0; # Script debugging, enable with --script-debug - -# Options FIXME not all.... +our $opt_verbose= 0; # Verbose output, enable with --verbose our $exe_master_mysqld; our $exe_mysql; @@ -173,13 +169,21 @@ our $exe_mysqladmin; our $exe_mysqlbinlog; our $exe_mysql_client_test; our $exe_mysqld; -our $exe_mysqldump; # Called from test case -our $exe_mysqlimport; # Called from test case -our $exe_mysqlshow; # Called from test case +our $exe_mysqlcheck; +our $exe_mysqldump; +our $exe_mysqlslap; +our $exe_mysqlimport; +our $exe_mysqlshow; our $exe_mysql_fix_system_tables; our $exe_mysqltest; +our $exe_ndbd; +our $exe_ndb_mgmd; our $exe_slave_mysqld; +our $exe_im; our $exe_my_print_defaults; +our $exe_perror; +our $lib_udf_example; +our $exe_libtool; our $opt_bench= 0; our $opt_small_bench= 0; @@ -187,10 +191,15 @@ our $opt_big_test= 0; # Send --big-test to mysqltest our @opt_extra_mysqld_opt; -our $opt_comment; our $opt_compress; -our $opt_current_test; -our $opt_ddd; +our $opt_ssl; +our $opt_skip_ssl; +our $opt_ssl_supported; +our $opt_ps_protocol; +our $opt_sp_protocol; +our $opt_cursor_protocol; +our $opt_view_protocol; + our $opt_debug; our $opt_do_test; our @opt_cases; # The test cases names in argv @@ -198,53 +207,60 @@ our $opt_embedded_server; our $opt_extern; our $opt_fast; our $opt_force; -our $opt_reorder; +our $opt_reorder= 0; +our $opt_enable_disabled; our $opt_gcov; our $opt_gcov_err; our $opt_gcov_msg; +our $glob_debugger= 0; our $opt_gdb; our $opt_client_gdb; +our $opt_ddd; +our $opt_client_ddd; our $opt_manual_gdb; +our $opt_manual_ddd; +our $opt_manual_debug; +our $opt_debugger; +our $opt_client_debugger; our $opt_gprof; our $opt_gprof_dir; our $opt_gprof_master; our $opt_gprof_slave; -our $opt_local; -our $opt_local_master; - -our $master; # Will be struct in C +our $master; our $slave; +our $clusters; + +our $instance_manager; our $opt_ndbcluster_port; our $opt_ndbconnectstring; - -our $opt_no_manager; # Does nothing now, we never use manager -our $opt_manager_port; # Does nothing now, we never use manager - -our $opt_old_master; +our $opt_ndbcluster_port_slave; +our $opt_ndbconnectstring_slave; our $opt_record; +our $opt_check_testcases; our $opt_result_ext; our $opt_skip; our $opt_skip_rpl; -our $opt_skip_im; # --skip-im on command line will just be ignored +our $max_slave_num= 0; +our $use_innodb; our $opt_skip_test; +our $opt_skip_im; our $opt_sleep; -our $opt_ps_protocol; our $opt_sleep_time_after_restart= 1; our $opt_sleep_time_for_delete= 10; our $opt_testcase_timeout; our $opt_suite_timeout; my $default_testcase_timeout= 15; # 15 min max -my $default_suite_timeout= 120; # 2 hours max +my $default_suite_timeout= 180; # 3 hours max our $opt_socket; @@ -256,18 +272,28 @@ our $opt_start_from; our $opt_strace_client; -our $opt_timer; +our $opt_timer= 1; our $opt_user; our $opt_user_test; -our $opt_valgrind; -our $opt_valgrind_mysqld; -our $opt_valgrind_mysqltest; -our $opt_valgrind_all; +our $opt_valgrind= 0; +our $opt_valgrind_mysqld= 0; +our $opt_valgrind_mysqltest= 0; +our $default_valgrind_options= "--show-reachable=yes"; our $opt_valgrind_options; +our $opt_valgrind_path; +our $opt_callgrind; -our $opt_verbose; +our $opt_stress= ""; +our $opt_stress_suite= "main"; +our $opt_stress_mode= "random"; +our $opt_stress_threads= 5; +our $opt_stress_test_count= 0; +our $opt_stress_loop_count= 0; +our $opt_stress_test_duration= 0; +our $opt_stress_init_file= ""; +our $opt_stress_test_file= ""; our $opt_wait_for_master; our $opt_wait_for_slave; @@ -277,17 +303,30 @@ our $opt_warnings; our $opt_udiff; -our $opt_skip_ndbcluster; -our $opt_with_ndbcluster; -our $opt_with_ndbcluster_only= 0; # dummy, ignored - -our $opt_with_openssl; +our $opt_skip_ndbcluster= 0; +our $opt_skip_ndbcluster_slave= 0; +our $opt_with_ndbcluster= 0; +our $opt_with_ndbcluster_only= 0; +our $opt_ndbcluster_supported= 0; +our $opt_ndb_extra_test= 0; +our $opt_skip_master_binlog= 0; +our $opt_skip_slave_binlog= 0; our $exe_ndb_mgm; +our $exe_ndb_waiter; our $path_ndb_tools_dir; -our $path_ndb_backup_dir; -our $file_ndb_testrun_log; -our $flag_ndb_status_ok= 1; +our $path_ndb_examples_dir; +our $exe_ndb_example; +our $path_ndb_testrun_log; + +our @data_dir_lst; + +our $used_binlog_format; +our $debug_compiled_binaries; +our $glob_tot_real_time= 0; + +# Default values read from mysqld +our $default_mysqld_port; ###################################################################### # @@ -298,27 +337,36 @@ our $flag_ndb_status_ok= 1; sub main (); sub initial_setup (); sub command_line_setup (); +sub snapshot_setup (); sub executable_setup (); sub environment_setup (); sub kill_running_server (); -sub kill_and_cleanup (); -sub ndbcluster_support (); -sub ndbcluster_install (); -sub ndbcluster_start (); -sub ndbcluster_stop (); +sub cleanup_stale_files (); +sub check_ssl_support ($); +sub check_running_as_root(); +sub check_ndbcluster_support ($); +sub rm_ndbcluster_tables ($); +sub ndbcluster_start_install ($); +sub ndbcluster_start ($$); +sub ndbcluster_wait_started ($$); +sub mysqld_wait_started($); sub run_benchmarks ($); -sub run_tests (); +sub initialize_servers (); sub mysql_install_db (); sub install_db ($$); +sub copy_install_db ($$); sub run_testcase ($); +sub run_testcase_stop_servers ($$$); +sub run_testcase_start_servers ($); +sub run_testcase_check_skip_test($); sub report_failure_and_restart ($); sub do_before_start_master ($$); sub do_before_start_slave ($$); -sub mysqld_start ($$$$); +sub ndbd_start ($$$); +sub ndb_mgmd_start ($); +sub mysqld_start ($$$); sub mysqld_arguments ($$$$$); -sub stop_masters_slaves (); -sub stop_masters (); -sub stop_slaves (); +sub stop_all_servers (); sub run_mysqltest ($); sub usage ($); @@ -335,12 +383,6 @@ sub main () { initial_setup(); command_line_setup(); executable_setup(); - - if (! $opt_skip_ndbcluster and ! $opt_with_ndbcluster) - { - $opt_with_ndbcluster= ndbcluster_support(); - } - environment_setup(); signal_setup(); @@ -354,44 +396,44 @@ sub main () { gprof_prepare(); } - if ( ! $glob_use_running_server ) - { - if ( $opt_start_dirty ) - { - kill_running_server(); - } - else - { - kill_and_cleanup(); - mysql_install_db(); - -# mysql_loadstd(); FIXME copying from "std_data" .frm and -# .MGR but there are none?! - } - } - - if ( $opt_start_dirty ) - { - if ( ndbcluster_start() ) - { - mtr_error("Can't start ndbcluster"); - } - if ( mysqld_start('master',0,[],[]) ) - { - mtr_report("Servers started, exiting"); - } - else - { - mtr_error("Can't start the mysqld server"); - } - } - elsif ( $opt_bench ) + if ( $opt_bench ) { + initialize_servers(); run_benchmarks(shift); # Shift what? Extra arguments?! } + elsif ( $opt_stress ) + { + initialize_servers(); + run_stress_test() + } else { - run_tests(); + # Figure out which tests we are going to run + my $tests= collect_test_cases($opt_suite); + + # Turn off NDB and other similar options if no tests use it + my ($need_ndbcluster,$need_im); + foreach my $test (@$tests) + { + $need_ndbcluster||= $test->{ndb_test}; + $need_im||= $test->{component_id} eq 'im'; + + # Count max number of slaves used by a test case + if ( $test->{slave_num} > $max_slave_num) + { + $max_slave_num= $test->{slave_num}; + mtr_error("Too many slaves") if $max_slave_num > 3; + } + $use_innodb||= $test->{'innodb_test'}; + } + $opt_skip_ndbcluster= $opt_skip_ndbcluster_slave= 1 + unless $need_ndbcluster; + $opt_skip_im= 1 unless $need_im; + + snapshot_setup(); + initialize_servers(); + + run_suite($opt_suite, $tests); } mtr_exit(0); @@ -410,13 +452,8 @@ sub initial_setup () { $glob_scriptname= basename($0); - $glob_win32_perl= ($^O eq "MSWin32"); - $glob_cygwin_perl= ($^O eq "cygwin"); - $glob_win32= ($glob_win32_perl or $glob_cygwin_perl); - # We require that we are in the "mysql-test" directory # to run mysql-test-run - if (! -f $glob_scriptname) { mtr_error("Can't find the location for the mysql-test-run script\n" . @@ -437,16 +474,13 @@ sub initial_setup () { { # Windows programs like 'mysqld' needs Windows paths $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`; - my $shell= $ENV{'SHELL'} || "/bin/bash"; - $glob_cygwin_shell= `cygpath -w "$shell"`; # The Windows path c:\... chomp($glob_mysql_test_dir); - chomp($glob_cygwin_shell); } $glob_basedir= dirname($glob_mysql_test_dir); - $glob_mysql_bench_dir= "$glob_basedir/mysql-bench"; # FIXME make configurable - # needs to be same length to test logging (FIXME what???) - $path_slave_load_tmpdir= "../../var/tmp"; + # Expect mysql-bench to be located adjacent to the source tree, by default + $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench" + unless defined $glob_mysql_bench_dir; $path_my_basedir= $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; @@ -467,9 +501,15 @@ sub command_line_setup () { # These are defaults for things that are set on the command line $opt_suite= "main"; # Special default suite - my $opt_master_myport= 9306; - my $opt_slave_myport= 9308; - $opt_ndbcluster_port= 9350; + my $opt_comment; + + my $opt_master_myport= 9306; + my $opt_slave_myport= 9308; + $opt_ndbcluster_port= 9310; + $opt_ndbcluster_port_slave= 9311; + my $im_port= 9312; + my $im_mysqld1_port= 9313; + my $im_mysqld2_port= 9314; # # To make it easier for different devs to work on the same host, @@ -488,9 +528,13 @@ sub command_line_setup () { if ( $ENV{'MTR_BUILD_THREAD'} ) { # Up to two masters, up to three slaves - $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 10 + 10000; # and 1 - $opt_slave_myport= $opt_master_myport + 2; # and 3 4 - $opt_ndbcluster_port= $opt_master_myport + 5; + $opt_master_myport= $ENV{'MTR_BUILD_THREAD'} * 10 + 10000; # and 1 + $opt_slave_myport= $opt_master_myport + 2; # and 3 4 + $opt_ndbcluster_port= $opt_master_myport + 5; + $opt_ndbcluster_port_slave= $opt_master_myport + 6; + $im_port= $opt_master_myport + 7; + $im_mysqld1_port= $opt_master_myport + 8; + $im_mysqld2_port= $opt_master_myport + 9; } if ( $opt_master_myport < 5001 or $opt_master_myport + 10 >= 32767 ) @@ -500,6 +544,11 @@ sub command_line_setup () { "($opt_master_myport - $opt_master_myport + 10)"); } + # This is needed for test log evaluation in "gen-build-status-page" + # in all cases where the calling tool does not log the commands + # directly before it executes them, like "make test-force-pl" in RPM builds. + print "Logging: $0 ", join(" ", @ARGV), "\n"; + # Read the command line # Note: Keep list, and the order, in sync with usage at end of this file @@ -508,42 +557,63 @@ sub command_line_setup () { # Control what engine/variation to run 'embedded-server' => \$opt_embedded_server, 'ps-protocol' => \$opt_ps_protocol, + 'sp-protocol' => \$opt_sp_protocol, + 'view-protocol' => \$opt_view_protocol, + 'cursor-protocol' => \$opt_cursor_protocol, + 'ssl|with-openssl' => \$opt_ssl, + 'skip-ssl' => \$opt_skip_ssl, + 'compress' => \$opt_compress, 'bench' => \$opt_bench, 'small-bench' => \$opt_small_bench, - 'no-manager' => \$opt_no_manager, # Currently not used # Control what test suites or cases to run 'force' => \$opt_force, 'with-ndbcluster' => \$opt_with_ndbcluster, - 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, 'with-ndbcluster-only' => \$opt_with_ndbcluster_only, + 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, + 'skip-ndbcluster-slave|skip-ndb-slave' + => \$opt_skip_ndbcluster_slave, + 'ndb-extra-test' => \$opt_ndb_extra_test, + 'skip-master-binlog' => \$opt_skip_master_binlog, + 'skip-slave-binlog' => \$opt_skip_slave_binlog, 'do-test=s' => \$opt_do_test, + 'start-from=s' => \$opt_start_from, 'suite=s' => \$opt_suite, 'skip-rpl' => \$opt_skip_rpl, - 'skip-im' => \$opt_skip_im, + 'skip-im' => \$opt_skip_im, 'skip-test=s' => \$opt_skip_test, + 'big-test' => \$opt_big_test, # Specify ports 'master_port=i' => \$opt_master_myport, 'slave_port=i' => \$opt_slave_myport, - 'ndbcluster_port=i' => \$opt_ndbcluster_port, - 'manager-port=i' => \$opt_manager_port, # Currently not used + 'ndbcluster-port|ndbcluster_port=i' => \$opt_ndbcluster_port, + 'ndbcluster-port-slave=i' => \$opt_ndbcluster_port_slave, + 'im-port=i' => \$im_port, # Instance Manager port. + 'im-mysqld1-port=i' => \$im_mysqld1_port, # Port of mysqld, controlled by IM + 'im-mysqld2-port=i' => \$im_mysqld2_port, # Port of mysqld, controlled by IM # Test case authoring 'record' => \$opt_record, + 'check-testcases' => \$opt_check_testcases, - # ??? + # Extra options used when starting mysqld 'mysqld=s' => \@opt_extra_mysqld_opt, # Run test on running server 'extern' => \$opt_extern, - 'ndbconnectstring=s' => \$opt_ndbconnectstring, + 'ndb-connectstring=s' => \$opt_ndbconnectstring, + 'ndb-connectstring-slave=s' => \$opt_ndbconnectstring_slave, # Debugging 'gdb' => \$opt_gdb, - 'manual-gdb' => \$opt_manual_gdb, 'client-gdb' => \$opt_client_gdb, + 'manual-gdb' => \$opt_manual_gdb, + 'manual-debug' => \$opt_manual_debug, 'ddd' => \$opt_ddd, + 'client-ddd' => \$opt_client_ddd, + 'debugger=s' => \$opt_debugger, + 'client-debugger=s' => \$opt_client_debugger, 'strace-client' => \$opt_strace_client, 'master-binary=s' => \$exe_master_mysqld, 'slave-binary=s' => \$exe_slave_mysqld, @@ -551,48 +621,54 @@ sub command_line_setup () { # Coverage, profiling etc 'gcov' => \$opt_gcov, 'gprof' => \$opt_gprof, - 'valgrind:s' => \$opt_valgrind, - 'valgrind-mysqltest:s' => \$opt_valgrind_mysqltest, - 'valgrind-all:s' => \$opt_valgrind_all, + 'valgrind|valgrind-all' => \$opt_valgrind, + 'valgrind-mysqltest' => \$opt_valgrind_mysqltest, + 'valgrind-mysqld' => \$opt_valgrind_mysqld, 'valgrind-options=s' => \$opt_valgrind_options, + 'valgrind-path=s' => \$opt_valgrind_path, + 'callgrind' => \$opt_callgrind, + + # Stress testing + 'stress' => \$opt_stress, + 'stress-suite=s' => \$opt_stress_suite, + 'stress-threads=i' => \$opt_stress_threads, + 'stress-test-file=s' => \$opt_stress_test_file, + 'stress-init-file=s' => \$opt_stress_init_file, + 'stress-mode=s' => \$opt_stress_mode, + 'stress-loop-count=i' => \$opt_stress_loop_count, + 'stress-test-count=i' => \$opt_stress_test_count, + 'stress-test-duration=i' => \$opt_stress_test_duration, + + # Directories + 'tmpdir=s' => \$opt_tmpdir, + 'vardir=s' => \$opt_vardir, + 'benchdir=s' => \$glob_mysql_bench_dir, # Misc - 'big-test' => \$opt_big_test, 'comment=s' => \$opt_comment, - 'compress' => \$opt_compress, 'debug' => \$opt_debug, 'fast' => \$opt_fast, - 'local' => \$opt_local, - 'local-master' => \$opt_local_master, - 'netware' => \$opt_netware, - 'old-master' => \$opt_old_master, 'reorder' => \$opt_reorder, + 'enable-disabled' => \$opt_enable_disabled, 'script-debug' => \$opt_script_debug, + 'verbose' => \$opt_verbose, 'sleep=i' => \$opt_sleep, 'socket=s' => \$opt_socket, 'start-dirty' => \$opt_start_dirty, 'start-and-exit' => \$opt_start_and_exit, - 'start-from=s' => \$opt_start_from, - 'timer' => \$opt_timer, - 'tmpdir=s' => \$opt_tmpdir, + 'timer!' => \$opt_timer, 'unified-diff|udiff' => \$opt_udiff, 'user-test=s' => \$opt_user_test, 'user=s' => \$opt_user, - 'vardir=s' => \$opt_vardir, - 'verbose' => \$opt_verbose, 'wait-timeout=i' => \$opt_wait_timeout, 'testcase-timeout=i' => \$opt_testcase_timeout, 'suite-timeout=i' => \$opt_suite_timeout, 'warnings|log-warnings' => \$opt_warnings, - 'with-openssl' => \$opt_with_openssl, 'help|h' => \$opt_usage, ) or usage("Can't read options"); - if ( $opt_usage ) - { - usage(""); - } + usage("") if $opt_usage; if ( $opt_comment ) { @@ -602,11 +678,6 @@ sub command_line_setup () { print '#' x 78, "\n\n"; } - if ( $opt_with_ndbcluster_only ) - { - print "# Option '--with-ndbcluster-only' is ignored in this release.\n"; - } - foreach my $arg ( @ARGV ) { if ( $arg =~ /^--skip-/ ) @@ -629,6 +700,21 @@ sub command_line_setup () { } } + # -------------------------------------------------------------------------- + # Find out type of logging that are being used + # -------------------------------------------------------------------------- + + # NOTE if the default binlog format is changed, this has to be changed + $used_binlog_format= "stmt"; + foreach my $arg ( @opt_extra_mysqld_opt ) + { + if ( defined mtr_match_substring($arg,"binlog-format=row")) + { + $used_binlog_format= "row"; + } + } + mtr_report("Using binlog format '$used_binlog_format'"); + # -------------------------------------------------------------------------- # Set the "var/" directory, as it is the base for everything else # -------------------------------------------------------------------------- @@ -637,6 +723,15 @@ sub command_line_setup () { { $opt_vardir= "$glob_mysql_test_dir/var"; } + elsif ( $mysql_version_id < 50000 ) + { + # --vardir was specified + mtr_error("--vardir option not supported until MySQL 5.0"); + } + + $path_vardir_trace= $opt_vardir; + # Chop off any "c:", DBUG likes a unix path ex: c:/src/... => /src/... + $path_vardir_trace=~ s/^\w://; # We make the path absolute, as the server will do a chdir() before usage unless ( $opt_vardir =~ m,^/, or @@ -652,27 +747,11 @@ sub command_line_setup () { $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir; $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any - # FIXME maybe not needed? - $path_manager_log= "$opt_vardir/log/manager.log" - unless $path_manager_log; - $opt_current_test= "$opt_vardir/log/current_test" - unless $opt_current_test; # -------------------------------------------------------------------------- # Do sanity checks of command line arguments # -------------------------------------------------------------------------- - if ( $opt_extern and $opt_local ) - { - mtr_error("Can't use --extern and --local at the same time"); - } - - if ( ! $opt_socket ) - { # FIXME set default before reading options? -# $opt_socket= '@MYSQL_UNIX_ADDR@'; - $opt_socket= "/tmp/mysql.sock"; # FIXME - } - # -------------------------------------------------------------------------- # Look at the command line options and set script flags # -------------------------------------------------------------------------- @@ -687,7 +766,8 @@ sub command_line_setup () { $glob_use_embedded_server= 1; push(@glob_test_mode, "embedded"); $opt_skip_rpl= 1; # We never run replication with embedded - $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster= 1; # Turn off use of NDB cluster + $opt_skip_ssl= 1; # Turn off use of SSL if ( $opt_extern ) { @@ -700,11 +780,40 @@ sub command_line_setup () { push(@glob_test_mode, "ps-protocol"); } - # FIXME don't understand what this is -# if ( $opt_local_master ) -# { -# $opt_master_myport= 3306; -# } + if ( $opt_with_ndbcluster and $opt_skip_ndbcluster) + { + mtr_error("Can't specify both --with-ndbcluster and --skip-ndbcluster"); + } + + if ( $opt_ndbconnectstring ) + { + $glob_use_running_ndbcluster= 1; + mtr_error("Can't specify --ndb-connectstring and --skip-ndbcluster") + if $opt_skip_ndbcluster; + mtr_error("Can't specify --ndb-connectstring and --ndbcluster-port") + if $opt_ndbcluster_port; + } + else + { + # Set default connect string + $opt_ndbconnectstring= "host=localhost:$opt_ndbcluster_port"; + } + + if ( $opt_ndbconnectstring_slave ) + { + $glob_use_running_ndbcluster_slave= 1; + mtr_error("Can't specify ndb-connectstring_slave and " . + "--skip-ndbcluster-slave") + if $opt_skip_ndbcluster; + mtr_error("Can't specify --ndb-connectstring-slave and " . + "--ndbcluster-port-slave") + if $opt_ndbcluster_port_slave; + } + else + { + # Set default connect string + $opt_ndbconnectstring_slave= "host=localhost:$opt_ndbcluster_port_slave"; + } if ( $opt_small_bench ) { @@ -721,83 +830,83 @@ sub command_line_setup () { mtr_error("Coverage test needs the source - please use source dist"); } - if ( $opt_gdb ) + # Check debug related options + if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd || + $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug || + $opt_debugger || $opt_client_debugger ) { + # Indicate that we are using debugger + $glob_debugger= 1; + # Increase timeouts $opt_wait_timeout= 300; if ( $opt_extern ) { - mtr_error("Can't use --extern with --gdb"); + mtr_error("Can't use --extern when using debugger"); } } - if ( $opt_manual_gdb ) + # Check IM arguments + if ( $glob_win32 ) { - $opt_gdb= 1; - if ( $opt_extern ) - { - mtr_error("Can't use --extern with --manual-gdb"); - } + mtr_report("Disable Instance manager - not supported on Windows"); + $opt_skip_im= 1; + } + # Check valgrind arguments + if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options) + { + mtr_report("Turning on valgrind for all executables"); + $opt_valgrind= 1; + $opt_valgrind_mysqld= 1; + $opt_valgrind_mysqltest= 1; + } + elsif ( $opt_valgrind_mysqld ) + { + mtr_report("Turning on valgrind for mysqld(s) only"); + $opt_valgrind= 1; + } + elsif ( $opt_valgrind_mysqltest ) + { + mtr_report("Turning on valgrind for mysqltest only"); + $opt_valgrind= 1; } - if ( $opt_ddd ) + if ( $opt_callgrind ) { - if ( $opt_extern ) - { - mtr_error("Can't use --extern with --ddd"); - } + mtr_report("Turning on valgrind with callgrind for mysqld(s)"); + $opt_valgrind= 1; + $opt_valgrind_mysqld= 1; + + # Set special valgrind options unless options passed on command line + $opt_valgrind_options="--trace-children=yes" + unless defined $opt_valgrind_options; } - if ( $opt_ndbconnectstring ) + if ( $opt_valgrind ) { - $glob_use_running_ndbcluster= 1; - $opt_with_ndbcluster= 1; - } - else - { - $opt_ndbconnectstring= "host=localhost:$opt_ndbcluster_port"; - } + # Set valgrind_options to default unless already defined + $opt_valgrind_options=$default_valgrind_options + unless defined $opt_valgrind_options; - if ( $opt_skip_ndbcluster ) - { - $opt_with_ndbcluster= 0; - } - - # The ":s" in the argument spec, means we have three different cases - # - # undefined option not set - # "" option set with no argument - # "somestring" option is name/path of valgrind executable - - # Take executable path from any of them, if any - $opt_valgrind_mysqld= $opt_valgrind; - $opt_valgrind= $opt_valgrind_mysqltest if $opt_valgrind_mysqltest; - $opt_valgrind= $opt_valgrind_all if $opt_valgrind_all; - - # If valgrind flag not defined, define if other valgrind flags are - unless ( defined $opt_valgrind ) - { - $opt_valgrind= "" - if defined $opt_valgrind_mysqltest or defined $opt_valgrind_all; + mtr_report("Running valgrind with options \"$opt_valgrind_options\""); } if ( ! $opt_testcase_timeout ) { $opt_testcase_timeout= $default_testcase_timeout; - $opt_testcase_timeout*= 10 if defined $opt_valgrind; + $opt_testcase_timeout*= 10 if $opt_valgrind; } if ( ! $opt_suite_timeout ) { $opt_suite_timeout= $default_suite_timeout; - $opt_suite_timeout*= 4 if defined $opt_valgrind; + $opt_suite_timeout*= 6 if $opt_valgrind; } - if ( defined $opt_valgrind ) + # Increase times to wait for executables to start if using valgrind + if ( $opt_valgrind ) { $opt_sleep_time_after_restart= 10; $opt_sleep_time_for_delete= 60; - # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr - # valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck" } if ( ! $opt_user ) @@ -812,74 +921,210 @@ sub command_line_setup () { } } + # On QNX, /tmp/dir/master.sock and /tmp/dir//master.sock seem to be + # considered different, so avoid the extra slash (/) in the socket + # paths. + my $sockdir = $opt_tmpdir; + $sockdir =~ s|/+$||; + # Put this into a hash, will be a C struct $master->[0]= { + pid => 0, + type => "master", + idx => 0, path_myddir => "$opt_vardir/master-data", path_myerr => "$opt_vardir/log/master.err", path_mylog => "$opt_vardir/log/master.log", - path_mypid => "$opt_vardir/run/master.pid", - path_mysock => "$opt_tmpdir/master.sock", - path_myport => $opt_master_myport, + path_pid => "$opt_vardir/run/master.pid", + path_sock => "$sockdir/master.sock", + port => $opt_master_myport, start_timeout => 400, # enough time create innodb tables - - ndbcluster => 1, # ndbcluster not started + cluster => 0, # index in clusters list + start_opts => [], }; $master->[1]= { + pid => 0, + type => "master", + idx => 1, path_myddir => "$opt_vardir/master1-data", path_myerr => "$opt_vardir/log/master1.err", path_mylog => "$opt_vardir/log/master1.log", - path_mypid => "$opt_vardir/run/master1.pid", - path_mysock => "$opt_tmpdir/master1.sock", - path_myport => $opt_master_myport + 1, + path_pid => "$opt_vardir/run/master1.pid", + path_sock => "$sockdir/master1.sock", + port => $opt_master_myport + 1, start_timeout => 400, # enough time create innodb tables + cluster => 0, # index in clusters list + start_opts => [], }; $slave->[0]= { + pid => 0, + type => "slave", + idx => 0, path_myddir => "$opt_vardir/slave-data", path_myerr => "$opt_vardir/log/slave.err", path_mylog => "$opt_vardir/log/slave.log", - path_mypid => "$opt_vardir/run/slave.pid", - path_mysock => "$opt_tmpdir/slave.sock", - path_myport => $opt_slave_myport, + path_pid => "$opt_vardir/run/slave.pid", + path_sock => "$sockdir/slave.sock", + port => $opt_slave_myport, start_timeout => 400, + + cluster => 1, # index in clusters list + start_opts => [], }; $slave->[1]= { + pid => 0, + type => "slave", + idx => 1, path_myddir => "$opt_vardir/slave1-data", path_myerr => "$opt_vardir/log/slave1.err", path_mylog => "$opt_vardir/log/slave1.log", - path_mypid => "$opt_vardir/run/slave1.pid", - path_mysock => "$opt_tmpdir/slave1.sock", - path_myport => $opt_slave_myport + 1, + path_pid => "$opt_vardir/run/slave1.pid", + path_sock => "$sockdir/slave1.sock", + port => $opt_slave_myport + 1, start_timeout => 300, + cluster => -1, # index in clusters list + start_opts => [], }; $slave->[2]= { + pid => 0, + type => "slave", + idx => 2, path_myddir => "$opt_vardir/slave2-data", path_myerr => "$opt_vardir/log/slave2.err", path_mylog => "$opt_vardir/log/slave2.log", - path_mypid => "$opt_vardir/run/slave2.pid", - path_mysock => "$opt_tmpdir/slave2.sock", - path_myport => $opt_slave_myport + 2, + path_pid => "$opt_vardir/run/slave2.pid", + path_sock => "$sockdir/slave2.sock", + port => $opt_slave_myport + 2, start_timeout => 300, + cluster => -1, # index in clusters list + start_opts => [], }; + $instance_manager= + { + path_err => "$opt_vardir/log/im.err", + path_log => "$opt_vardir/log/im.log", + path_pid => "$opt_vardir/run/im.pid", + path_angel_pid => "$opt_vardir/run/im.angel.pid", + path_sock => "$sockdir/im.sock", + port => $im_port, + start_timeout => $master->[0]->{'start_timeout'}, + admin_login => 'im_admin', + admin_password => 'im_admin_secret', + admin_sha1 => '*598D51AD2DFF7792045D6DF3DDF9AA1AF737B295', + password_file => "$opt_vardir/im.passwd", + defaults_file => "$opt_vardir/im.cnf", + }; + + $instance_manager->{'instances'}->[0]= + { + server_id => 1, + port => $im_mysqld1_port, + path_datadir => "$opt_vardir/im_mysqld_1.data", + path_sock => "$sockdir/mysqld_1.sock", + path_pid => "$opt_vardir/run/mysqld_1.pid", + start_timeout => 400, # enough time create innodb tables + old_log_format => 1 + }; + + $instance_manager->{'instances'}->[1]= + { + server_id => 2, + port => $im_mysqld2_port, + path_datadir => "$opt_vardir/im_mysqld_2.data", + path_sock => "$sockdir/mysqld_2.sock", + path_pid => "$opt_vardir/run/mysqld_2.pid", + nonguarded => 1, + start_timeout => 400, # enough time create innodb tables + old_log_format => 1 + }; + + my $data_dir= "$opt_vardir/ndbcluster-$opt_ndbcluster_port"; + $clusters->[0]= + { + name => "Master", + nodes => 2, + port => "$opt_ndbcluster_port", + data_dir => "$data_dir", + connect_string => "$opt_ndbconnectstring", + path_pid => "$data_dir/ndb_3.pid", # Nodes + 1 + pid => 0, # pid of ndb_mgmd + installed_ok => 0, + }; + + $data_dir= "$opt_vardir/ndbcluster-$opt_ndbcluster_port_slave"; + $clusters->[1]= + { + name => "Slave", + nodes => 1, + port => "$opt_ndbcluster_port_slave", + data_dir => "$data_dir", + connect_string => "$opt_ndbconnectstring_slave", + path_pid => "$data_dir/ndb_2.pid", # Nodes + 1 + pid => 0, # pid of ndb_mgmd + installed_ok => 0, + }; + + # Init pids of ndbd's + foreach my $cluster ( @{$clusters} ) + { + for ( my $idx= 0; $idx < $cluster->{'nodes'}; $idx++ ) + { + my $nodeid= $idx+1; + $cluster->{'ndbds'}->[$idx]= + { + pid => 0, + nodeid => $nodeid, + path_pid => "$cluster->{'data_dir'}/ndb_${nodeid}.pid", + path_fs => "$cluster->{'data_dir'}/ndb_${nodeid}_fs", + }; + } + } + if ( $opt_extern ) { $glob_use_running_server= 1; $opt_skip_rpl= 1; # We don't run rpl test cases - $master->[0]->{'path_mysock'}= $opt_socket; + $master->[0]->{'path_sock'}= $opt_socket; } $path_timefile= "$opt_vardir/log/mysqltest-time"; $path_mysqltest_log= "$opt_vardir/log/mysqltest.log"; + $path_current_test_log= "$opt_vardir/log/current_test"; + $path_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log"; + + $path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/"; +} + +sub snapshot_setup () { + + # Make a list of all data_dirs + @data_dir_lst = ( + $master->[0]->{'path_myddir'}, + $master->[1]->{'path_myddir'}); + + for (my $idx= 0; $idx < $max_slave_num; $idx++) + { + push(@data_dir_lst, $slave->[$idx]->{'path_myddir'}); + } + + unless ($opt_skip_im) + { + foreach my $instance (@{$instance_manager->{'instances'}}) + { + push(@data_dir_lst, $instance->{'path_datadir'}); + } + } } @@ -889,136 +1134,222 @@ sub command_line_setup () { # ############################################################################## + +sub check_mysqld_features () { + # + # Execute "mysqld --no-defaults --help --verbose", that will + # print out version and a list of all features and settings + # + my $found_variable_list_start= 0; + my $spec_file= "$opt_vardir/tmp/mysqld.spec"; + if ( mtr_run($exe_mysqld, + ["--no-defaults", + "--verbose", + "--help"], + "", "$spec_file", "$spec_file", "") != 0 ) + { + mtr_error("Failed to get version and list of features from %s", + $exe_mysqld); + } + + my %mysqld_variables; + my $F= IO::File->new($spec_file) or + mtr_error("can't open file \"$spec_file\": $!"); + + while ( my $line= <$F> ) + { + # First look for version + if ( !$mysql_version_id ) + { + # Look for version + if ( $line =~ /^$exe_mysqld\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ ) + { + print "Major: $1 Minor: $2 Build: $3\n"; + $mysql_version_id= $1*10000 + $2*100 + $3; + print "mysql_version_id: $mysql_version_id\n"; + } + } + else + { + if (!$found_variable_list_start) + { + # Look for start of variables list + if ( $line =~ /-*\s-*/ ) + { + $found_variable_list_start= 1; + } + } else { + # Put variables into hash + if ( $line =~ /^(\w*)[ \t]*(\w*)$/ ) + { + $mysqld_variables{$1}= $2; + } + } + } + } + mtr_error("Could not find version of MySQL") unless $mysql_version_id; + + check_ndbcluster_support(\%mysqld_variables); + check_ssl_support(\%mysqld_variables); + check_debug_support(\%mysqld_variables); + + if ( $mysql_version_id < 50000 ) + { + # Instance manager is not supported until 5.0 + $opt_skip_im= 1; + } + + # Set default values from mysqld_variables + $opt_socket= %mysqld_variables->{'socket'}; + $default_mysqld_port = %mysqld_variables->{'port'}; +} + + sub executable_setup () { - if ( $opt_source_dist ) + # + # Check if libtool is available in this distribution/clone + # we need it when valgrinding or debugging non installed binary + # Otherwise valgrind will valgrind the libtool wrapper or bash + # and gdb will not find the real executable to debug + # + if ( -x "../libtool") { - if ( $glob_win32 ) + $exe_libtool= "../libtool"; + if ($opt_valgrind or $glob_debugger) { - $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", - "$glob_basedir/bin"); - $exe_mysqld= mtr_exe_exists ("$path_client_bindir/mysqld-nt", - "$path_client_bindir/mysqld", - "$path_client_bindir/mysqld-debug", - "$path_client_bindir/mysqld-max", - "$path_client_bindir/mysqld-max-nt"); - $path_language= mtr_path_exists("$glob_basedir/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets"); - $exe_my_print_defaults= - mtr_exe_exists("$path_client_bindir/my_print_defaults"); + mtr_report("Using \"$exe_libtool\" when running valgrind or debugger"); } - else - { - $path_client_bindir= mtr_path_exists("$glob_basedir/client"); - $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld"); - $path_language= mtr_path_exists("$glob_basedir/sql/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/sql/share/charsets"); - $exe_my_print_defaults= - mtr_exe_exists("$glob_basedir/extra/my_print_defaults"); - } - - if ( $glob_use_embedded_server ) - { - my $path_examples= "$glob_basedir/libmysqld/examples"; - $exe_mysqltest= mtr_exe_exists("$path_examples/mysqltest_embedded"); - $exe_mysql_client_test= - mtr_exe_exists("$path_examples/mysql_client_test_embedded", - "/usr/bin/false"); - } - else - { - if ( $opt_valgrind_mysqltest ) - { - # client/mysqltest might be a libtool .sh script, so look for real exe - # to avoid valgrinding bash ;) - $exe_mysqltest= - mtr_exe_exists("$path_client_bindir/.libs/lt-mysqltest", - "$path_client_bindir/.libs/mysqltest", - "$path_client_bindir/mysqltest"); - } - else - { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); - } - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test", - "/usr/bin/false"); - } - $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); - $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); - $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); - $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); - $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); - $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); - $exe_mysql_fix_system_tables= - mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables"); - $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools"); - $exe_ndb_mgm= "$glob_basedir/ndb/src/mgmclient/ndb_mgm"; } - else - { - $path_client_bindir= mtr_path_exists("$glob_basedir/bin"); - $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); - $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); - $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); - $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); - $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); - $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); - $exe_mysql_fix_system_tables= - mtr_script_exists("$path_client_bindir/mysql_fix_privilege_tables", - "$glob_basedir/scripts/mysql_fix_privilege_tables"); - $exe_my_print_defaults= - mtr_exe_exists("$path_client_bindir/my_print_defaults"); - $path_language= mtr_path_exists("$glob_basedir/share/mysql/english/", - "$glob_basedir/share/english/"); - $path_charsetsdir= mtr_path_exists("$glob_basedir/share/mysql/charsets", - "$glob_basedir/share/charsets"); + # Look for the path where to find the client binaries + $path_client_bindir= mtr_path_exists("$glob_basedir/client", + "$glob_basedir/client_release", + "$glob_basedir/client_debug", + "$glob_basedir/client/release", + "$glob_basedir/client/debug", + "$glob_basedir/bin"); - if ( $glob_win32 ) - { - $exe_mysqld= mtr_exe_exists ("$glob_basedir/bin/mysqld-nt", - "$glob_basedir/bin/mysqld", - "$glob_basedir/bin/mysqld-debug",); - } - else - { - $exe_mysqld= mtr_exe_exists ("$glob_basedir/libexec/mysqld", - "$glob_basedir/bin/mysqld"); - } - - if ( $glob_use_embedded_server ) - { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest_embedded"); - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test_embedded", - "$path_client_bindir/mysql_client_test_embedded", - "/usr/bin/false"); - } - else - { - $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); - $exe_mysql_client_test= - mtr_exe_exists("$path_client_bindir/mysql_client_test", - "/usr/bin/false"); # FIXME temporary - } - - $path_ndb_tools_dir= "$glob_basedir/bin"; - $exe_ndb_mgm= "$glob_basedir/bin/ndb_mgm"; - } + # Look for the mysqld executable + $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld", + "$path_client_bindir/mysqld-max-nt", + "$path_client_bindir/mysqld-max", + "$path_client_bindir/mysqld-nt", + "$path_client_bindir/mysqld", + "$path_client_bindir/mysqld-debug", + "$path_client_bindir/mysqld-max", + "$glob_basedir/libexec/mysqld", + "$glob_basedir/sql/release/mysqld", + "$glob_basedir/sql/debug/mysqld"); $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; - $path_ndb_backup_dir= - "$opt_vardir/ndbcluster-$opt_ndbcluster_port"; - $file_ndb_testrun_log= "$opt_vardir/log/ndb_testrun.log"; + # Use the mysqld found above to find out what features are available + check_mysqld_features(); + + # Look for language files and charsetsdir, use same share + my $path_share= mtr_path_exists("$glob_basedir/share", + "$glob_basedir/sql/share", + "$glob_basedir/share/mysql", + "$glob_basedir/share"); + + $path_language= mtr_path_exists("$path_share/english"); + $path_charsetsdir= mtr_path_exists("$path_share/charsets"); + + # Look for my_print_defaults + $exe_my_print_defaults= + mtr_exe_exists("$path_client_bindir/my_print_defaults", + "$glob_basedir/extra/my_print_defaults", + "$glob_basedir/extra/release/my_print_defaults", + "$glob_basedir/extra/debug/my_print_defaults"); + + # Look for perror + $exe_perror= mtr_exe_exists("$glob_basedir/extra/perror", + "$path_client_bindir/perror", + "$glob_basedir/extra/release/perror", + "$glob_basedir/extra/debug/perror"); + + + if ( ! $opt_skip_im ) + { + # Look for instance manager binary - mysqlmanager + $exe_im= + mtr_exe_exists( + "$glob_basedir/server-tools/instance-manager/mysqlmanager", + "$glob_basedir/libexec/mysqlmanager"); + } + + # Look for the client binaries + $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); + $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); + $exe_mysqlimport= mtr_exe_exists("$path_client_bindir/mysqlimport"); + $exe_mysqlshow= mtr_exe_exists("$path_client_bindir/mysqlshow"); + $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); + $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); + $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); + + # Look for mysql_fix_system_table script + $exe_mysql_fix_system_tables= + mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", + "$path_client_bindir/mysql_fix_privilege_tables"); + + if ( $opt_with_ndbcluster) + { + # Look for ndb tols and binaries + $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools", + "$glob_basedir/bin"); + $exe_ndb_mgm= mtr_exe_exists("$glob_basedir/ndb/src/mgmclient/ndb_mgm", + "$glob_basedir/bin/ndb_mgm"); + } + + # Look for the udf_example library + $lib_udf_example= + mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so"); + + + # Look for mysqltest executable + if ( $glob_use_embedded_server ) + { + $exe_mysqltest= + mtr_exe_exists("$glob_basedir/libmysqld/examples/mysqltest_embedded", + "$path_client_bindir/mysqltest_embedded"); + } + else + { + $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); + + + } + + # Look for mysql_client_test executable + if ( $glob_use_embedded_server ) + { + $exe_mysql_client_test= + mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded", + "$glob_basedir/tests/mysqltest_embedded"); + } + else + { + $exe_mysql_client_test= + mtr_exe_exists("$glob_basedir/tests/mysql_client_test"); + } +} + + +sub generate_cmdline_mysqldump ($) { + my($mysqld) = @_; + return + "$exe_mysqldump --no-defaults -uroot " . + "--port=$mysqld->{'port'} " . + "--socket=$mysqld->{'path_sock'} --password="; } ############################################################################## # -# Set environment to be used by childs of this process +# Set environment to be used by childs of this process for +# things that are constant duting the whole lifetime of mysql-test-run.pl # ############################################################################## @@ -1026,65 +1357,320 @@ sub executable_setup () { sub environment_setup () { - # -------------------------------------------------------------------------- - # We might not use a standard installation directory, like /usr/lib. - # Set LD_LIBRARY_PATH to make sure we find our installed libraries. - # -------------------------------------------------------------------------- + umask(022); - unless ( $opt_source_dist ) + my @ld_library_paths; + + # -------------------------------------------------------------------------- + # Setup LD_LIBRARY_PATH so the libraries from this distro/clone + # are used in favor of the system installed ones + # -------------------------------------------------------------------------- + if ( $opt_source_dist ) { - $ENV{'LD_LIBRARY_PATH'}= - "$glob_basedir/lib" . - ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); - $ENV{'DYLD_LIBRARY_PATH'}= - "$glob_basedir/lib" . - ($ENV{'DYLD_LIBRARY_PATH'} ? ":$ENV{'DYLD_LIBRARY_PATH'}" : ""); + push(@ld_library_paths, "$glob_basedir/libmysql/.libs/", + "$glob_basedir/libmysql_r/.libs/"); } + else + { + push(@ld_library_paths, "$glob_basedir/lib"); + } + + # -------------------------------------------------------------------------- + # Add the path where libndbclient can be found + # -------------------------------------------------------------------------- + if ( $opt_ndbcluster_supported ) + { + push(@ld_library_paths, "$glob_basedir/storage/ndb/src/.libs"); + } + + # -------------------------------------------------------------------------- + # Add the path where mysqld will find udf_example.so + # -------------------------------------------------------------------------- + if ( $lib_udf_example ) + { + push(@ld_library_paths, dirname($lib_udf_example)); + } + + # -------------------------------------------------------------------------- + # Valgrind need to be run with debug libraries otherwise it's almost + # impossible to add correct supressions, that means if "/usr/lib/debug" + # is available, it should be added to + # LD_LIBRARY_PATH + # -------------------------------------------------------------------------- + my $debug_libraries_path= "/usr/lib/debug"; + if ( $opt_valgrind and -d $debug_libraries_path ) + { + push(@ld_library_paths, $debug_libraries_path); + } + + $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths, + split(':', $ENV{'LD_LIBRARY_PATH'})); + mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}"); + + $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths, + split(':', $ENV{'DYLD_LIBRARY_PATH'})); + mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}"); + # -------------------------------------------------------------------------- # Also command lines in .opt files may contain env vars # -------------------------------------------------------------------------- + $ENV{'CHARSETSDIR'}= $path_charsetsdir; $ENV{'UMASK'}= "0660"; # The octal *string* $ENV{'UMASK_DIR'}= "0770"; # The octal *string* $ENV{'LC_COLLATE'}= "C"; $ENV{'USE_RUNNING_SERVER'}= $glob_use_running_server; $ENV{'MYSQL_TEST_DIR'}= $glob_mysql_test_dir; - $ENV{'MYSQL_TEST_WINDIR'}= $glob_mysql_test_dir; $ENV{'MYSQLTEST_VARDIR'}= $opt_vardir; - $ENV{'MASTER_WINMYSOCK'}= $master->[0]->{'path_mysock'}; - $ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_mysock'}; - $ENV{'MASTER_MYSOCK1'}= $master->[1]->{'path_mysock'}; - $ENV{'MASTER_MYPORT'}= $master->[0]->{'path_myport'}; - $ENV{'MASTER_MYPORT1'}= $master->[1]->{'path_myport'}; - $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'path_myport'}; - $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'path_myport'}; - $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'path_myport'}; -# $ENV{'MYSQL_TCP_PORT'}= '@MYSQL_TCP_PORT@'; # FIXME - $ENV{'MYSQL_TCP_PORT'}= 3306; - - $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; - - if ( $glob_cygwin_perl ) - { - foreach my $key ('MYSQL_TEST_WINDIR','MASTER_MYSOCK') - { - $ENV{$key}= `cygpath -w $ENV{$key}`; - $ENV{$key} =~ s,\\,\\\\,g; - chomp($ENV{$key}); - } - } + $ENV{'MYSQL_TMP_DIR'}= $opt_tmpdir; + $ENV{'MASTER_MYSOCK'}= $master->[0]->{'path_sock'}; + $ENV{'MASTER_MYSOCK1'}= $master->[1]->{'path_sock'}; + $ENV{'MASTER_MYPORT'}= $master->[0]->{'port'}; + $ENV{'MASTER_MYPORT1'}= $master->[1]->{'port'}; + $ENV{'SLAVE_MYSOCK'}= $slave->[0]->{'path_sock'}; + $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'port'}; + $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'port'}; + $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'}; + $ENV{'MYSQL_TCP_PORT'}= $default_mysqld_port; $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set + # ---------------------------------------------------- + # Setup env for NDB + # ---------------------------------------------------- + $ENV{'NDB_MGM'}= $exe_ndb_mgm; + + $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; + $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave; + + $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test; + + $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; + $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; + $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; + + $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; + $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; + $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; + + # ---------------------------------------------------- + # Setup env for IM + # ---------------------------------------------------- + $ENV{'IM_EXE'}= $exe_im; + $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid}; + $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid}; + $ENV{'IM_PORT'}= $instance_manager->{port}; + $ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file}; + $ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file}; + + $ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock}; + $ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port}; + $ENV{'IM_MYSQLD1_PATH_PID'}=$instance_manager->{instances}->[0]->{path_pid}; + $ENV{'IM_MYSQLD2_SOCK'}= $instance_manager->{instances}->[1]->{path_sock}; + $ENV{'IM_MYSQLD2_PORT'}= $instance_manager->{instances}->[1]->{port}; + $ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid}; + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlcheck + # ---------------------------------------------------- + my $cmdline_mysqlcheck= + "$exe_mysqlcheck --no-defaults -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password="; + + if ( $opt_debug ) + { + $cmdline_mysqlcheck .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlcheck.trace"; + } + $ENV{'MYSQL_CHECK'}= $cmdline_mysqlcheck; + + # ---------------------------------------------------- + # Setup env to childs can execute myqldump + # ---------------------------------------------------- + my $cmdline_mysqldump= generate_cmdline_mysqldump($master->[0]); + my $cmdline_mysqldumpslave= generate_cmdline_mysqldump($slave->[0]); + + if ( $opt_debug ) + { + $cmdline_mysqldump .= + " --debug=d:t:A,$path_vardir_trace/log/mysqldump-master.trace"; + $cmdline_mysqldumpslave .= + " --debug=d:t:A,$path_vardir_trace/log/mysqldump-slave.trace"; + } + $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump; + $ENV{'MYSQL_DUMP_SLAVE'}= $cmdline_mysqldumpslave; + + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlslap + # ---------------------------------------------------- + unless ( $glob_win32 ) + { + my $cmdline_mysqlslap= + "$exe_mysqlslap -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password= " . + "--lock-directory=$opt_tmpdir"; + + if ( $opt_debug ) + { + $cmdline_mysqlslap .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; + } + $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap; + } + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlimport + # ---------------------------------------------------- + my $cmdline_mysqlimport= + "$exe_mysqlimport -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password="; + + if ( $opt_debug ) + { + $cmdline_mysqlimport .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlimport.trace"; + } + $ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport; + + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlshow + # ---------------------------------------------------- + my $cmdline_mysqlshow= + "$exe_mysqlshow -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password="; + + if ( $opt_debug ) + { + $cmdline_mysqlshow .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlshow.trace"; + } + $ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow; + + # ---------------------------------------------------- + # Setup env so childs can execute mysqlbinlog + # ---------------------------------------------------- + my $cmdline_mysqlbinlog= + "$exe_mysqlbinlog" . + " --no-defaults --local-load=$opt_tmpdir"; + if ( $mysql_version_id >= 50000 ) + { + $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir"; + } + + if ( $opt_debug ) + { + $cmdline_mysqlbinlog .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlbinlog.trace"; + } + $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog; + + # ---------------------------------------------------- + # Setup env so childs can execute mysql + # ---------------------------------------------------- + my $cmdline_mysql= + "$exe_mysql --no-defaults --host=localhost --user=root --password= " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} ". + "--character-sets-dir=$path_charsetsdir"; + + $ENV{'MYSQL'}= $cmdline_mysql; + + # ---------------------------------------------------- + # Setup env so childs can execute mysql_client_test + # ---------------------------------------------------- + my $cmdline_mysql_client_test= + "$exe_mysql_client_test --no-defaults --testcase --user=root --silent " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'}"; + if ( $mysql_version_id >= 50000 ) + { + $cmdline_mysql_client_test .=" --vardir=$opt_vardir"; + } + + if ( $opt_debug ) + { + $cmdline_mysql_client_test .= + " --debug=d:t:A,$path_vardir_trace/log/mysql_client_test.trace"; + } + + if ( $glob_use_embedded_server ) + { + $cmdline_mysql_client_test.= + " -A --language=$path_language" . + " -A --datadir=$slave->[0]->{'path_myddir'}" . + " -A --character-sets-dir=$path_charsetsdir"; + } + $ENV{'MYSQL_CLIENT_TEST'}= $cmdline_mysql_client_test; + + + # ---------------------------------------------------- + # Setup env so childs can execute mysql_fix_system_tables + # ---------------------------------------------------- + my $cmdline_mysql_fix_system_tables= + "$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " . + "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'}"; + + $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; + + # ---------------------------------------------------- + # Setup env so childs can execute my_print_defaults + # ---------------------------------------------------- + $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; + + + # ---------------------------------------------------- + # Setup env so childs can execute perror + # ---------------------------------------------------- + $ENV{'MY_PERROR'}= $exe_perror; + + # ---------------------------------------------------- + # Add the path where mysqld will find udf_example.so + # ---------------------------------------------------- + $ENV{'UDF_EXAMPLE_LIB'}= + ($lib_udf_example ? basename($lib_udf_example) : ""); + + $ENV{'LD_LIBRARY_PATH'}= + ($lib_udf_example ? dirname($lib_udf_example) : "") . + ($ENV{'LD_LIBRARY_PATH'} ? ":$ENV{'LD_LIBRARY_PATH'}" : ""); + + + # ---------------------------------------------------- # We are nice and report a bit about our settings - print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; - print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; - print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; - print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; - print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; - print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; - print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; + # ---------------------------------------------------- + if (!$opt_extern) + { + print "Using MTR_BUILD_THREAD = $ENV{MTR_BUILD_THREAD}\n"; + print "Using MASTER_MYPORT = $ENV{MASTER_MYPORT}\n"; + print "Using MASTER_MYPORT1 = $ENV{MASTER_MYPORT1}\n"; + print "Using SLAVE_MYPORT = $ENV{SLAVE_MYPORT}\n"; + print "Using SLAVE_MYPORT1 = $ENV{SLAVE_MYPORT1}\n"; + print "Using SLAVE_MYPORT2 = $ENV{SLAVE_MYPORT2}\n"; + if ( ! $opt_skip_ndbcluster ) + { + print "Using NDBCLUSTER_PORT = $ENV{NDBCLUSTER_PORT}\n"; + if ( ! $opt_skip_ndbcluster_slave ) + { + print "Using NDBCLUSTER_PORT_SLAVE = $ENV{NDBCLUSTER_PORT_SLAVE}\n"; + } + } + if ( ! $opt_skip_im ) + { + print "Using IM_PORT = $ENV{IM_PORT}\n"; + print "Using IM_MYSQLD1_PORT = $ENV{IM_MYSQLD1_PORT}\n"; + print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; + } + } } @@ -1099,10 +1685,11 @@ sub signal_setup () { $SIG{INT}= \&handle_int_signal; } + sub handle_int_signal () { $SIG{INT}= 'DEFAULT'; # If we get a ^C again, we die... mtr_warning("got INT signal, cleaning up....."); - stop_masters_slaves(); + stop_all_servers(); mtr_error("We die from ^C signal from user"); } @@ -1118,31 +1705,24 @@ sub kill_running_server () { if ( $opt_fast or $glob_use_embedded_server ) { # FIXME is embedded server really using PID files?! - unlink($master->[0]->{'path_mypid'}); - unlink($master->[1]->{'path_mypid'}); - unlink($slave->[0]->{'path_mypid'}); - unlink($slave->[1]->{'path_mypid'}); - unlink($slave->[2]->{'path_mypid'}); + unlink($master->[0]->{'path_pid'}); + unlink($master->[1]->{'path_pid'}); + unlink($slave->[0]->{'path_pid'}); + unlink($slave->[1]->{'path_pid'}); + unlink($slave->[2]->{'path_pid'}); } else { # Ensure that no old mysqld test servers are running # This is different from terminating processes we have - # started from ths run of the script, this is terminating + # started from this run of the script, this is terminating # leftovers from previous runs. - mtr_report("Killing Possible Leftover Processes"); - mkpath("$opt_vardir/log"); # Needed for mysqladmin log mtr_kill_leftovers(); - - ndbcluster_stop(); - $master->[0]->{'ndbcluster'}= 1; - } + } } -sub kill_and_cleanup () { - - kill_running_server (); +sub cleanup_stale_files () { mtr_report("Removing Stale Files"); @@ -1186,16 +1766,7 @@ sub kill_and_cleanup () { mkpath("$opt_vardir/tmp"); mkpath($opt_tmpdir) if $opt_tmpdir ne "$opt_vardir/tmp"; - # FIXME do we really need to create these all, or are they - # created for us when tables are created? - - my @data_dir_lst = ( - $master->[0]->{'path_myddir'}, - $master->[1]->{'path_myddir'}, - $slave->[0]->{'path_myddir'}, - $slave->[1]->{'path_myddir'}, - $slave->[2]->{'path_myddir'}); - + # Remove old and create new data dirs foreach my $data_dir (@data_dir_lst) { rmtree("$data_dir"); @@ -1214,104 +1785,353 @@ sub kill_and_cleanup () { mkpath("$opt_vardir/std_data_ln"); opendir(DIR, "$glob_mysql_test_dir/std_data") or mtr_error("Can't find the std_data directory: $!"); - for my $elem ( readdir(DIR) ) { - next if -d "$glob_mysql_test_dir/std_data/$elem"; - copy("$glob_mysql_test_dir/std_data/$elem", "$opt_vardir/std_data_ln/$elem"); + for(readdir(DIR)) { + next if -d "$glob_mysql_test_dir/std_data/$_"; + copy("$glob_mysql_test_dir/std_data/$_", "$opt_vardir/std_data_ln/$_"); } closedir(DIR); } } +sub check_running_as_root () { + # Check if running as root + # i.e a file can be read regardless what mode we set it to + my $test_file= "$opt_vardir/test_running_as_root.txt"; + mtr_tofile($test_file, "MySQL"); + chmod(oct("0000"), $test_file); + + my $result=""; + if (open(FILE,"<",$test_file)) + { + $result= join('', ); + close FILE; + } + + chmod(oct("0755"), $test_file); + unlink($test_file); + + $ENV{'MYSQL_TEST_ROOT'}= "NO"; + if ($result eq "MySQL") + { + mtr_warning("running this script as _root_ will cause some " . + "tests to be skipped"); + $ENV{'MYSQL_TEST_ROOT'}= "YES"; + } +} + + +sub check_ssl_support ($) { + my $mysqld_variables= shift; + + if ($opt_skip_ssl || $opt_extern) + { + mtr_report("Skipping SSL"); + $opt_ssl_supported= 0; + $opt_ssl= 0; + return; + } + + if ( $mysqld_variables->{'ssl'} eq "FALSE" ) + { + if ( $opt_ssl) + { + mtr_error("Couldn't find support for SSL"); + return; + } + mtr_report("Skipping SSL, mysqld not compiled with SSL"); + $opt_ssl_supported= 0; + $opt_ssl= 0; + return; + } + mtr_report("Setting mysqld to support SSL connections"); + $opt_ssl_supported= 1; +} + + +sub check_debug_support ($) { + my $mysqld_variables= shift; + + if ( $mysqld_variables->{'debug'} ) + { + #mtr_report("Binaries are not debug compiled"); + $debug_compiled_binaries= 0; + + if ( $opt_debug ) + { + mtr_error("Can't use --debug, binaries does not support it"); + } + return; + } + mtr_report("Binaries are debug compiled"); + $debug_compiled_binaries= 1; +} + ############################################################################## # # Start the ndb cluster # ############################################################################## -sub ndbcluster_support () { +sub check_ndbcluster_support ($) { + my $mysqld_variables= shift; - # check ndbcluster support by testing using a switch - # that is only available in that case - if ( mtr_run($exe_mysqld, - ["--no-defaults", - "--ndb-use-exact-count", - "--help"], - "", "/dev/null", "/dev/null", "") != 0 ) - { - mtr_report("No ndbcluster support"); - return 0; - } - mtr_report("Has ndbcluster support"); - return 1; -} - -# FIXME why is there a different start below?! - -sub ndbcluster_install () { - - if ( ! $opt_with_ndbcluster or $glob_use_running_ndbcluster ) - { - return 0; - } - mtr_report("Install ndbcluster"); - my $ndbcluster_opts= $opt_bench ? "" : "--small"; - my $ndbcluster_port_base= $opt_ndbcluster_port + 2; - if ( mtr_run("$glob_mysql_test_dir/ndb/ndbcluster", - ["--port=$opt_ndbcluster_port", - "--port-base=$ndbcluster_port_base", - "--data-dir=$opt_vardir", - $ndbcluster_opts, - "--initial"], - "", "", "", "") ) - { - mtr_error("Error ndbcluster_install"); - return 1; - } - - ndbcluster_stop(); - $master->[0]->{'ndbcluster'}= 1; - - return 0; -} - -sub ndbcluster_start () { - - if ( ! $opt_with_ndbcluster or $glob_use_running_ndbcluster ) - { - return 0; - } - # FIXME, we want to _append_ output to file $file_ndb_testrun_log instead of /dev/null - if ( mtr_run("$glob_mysql_test_dir/ndb/ndbcluster", - ["--port=$opt_ndbcluster_port", - "--data-dir=$opt_vardir"], - "", "/dev/null", "", "") ) - { - mtr_error("Error ndbcluster_start"); - return 1; - } - - return 0; -} - -sub ndbcluster_stop () { - - if ( ! $opt_with_ndbcluster or $glob_use_running_ndbcluster ) + if ($opt_skip_ndbcluster) { + mtr_report("Skipping ndbcluster"); + $opt_skip_ndbcluster_slave= 1; return; } - my $ndbcluster_port_base= $opt_ndbcluster_port + 2; - # FIXME, we want to _append_ output to file $file_ndb_testrun_log instead of /dev/null - mtr_run("$glob_mysql_test_dir/ndb/ndbcluster", - ["--port=$opt_ndbcluster_port", - "--data-dir=$opt_vardir", - "--stop"], - "", "/dev/null", "", ""); + if ( $mysqld_variables->{'ndbcluster'} eq "FALSE") + { + mtr_report("Skipping ndbcluster, mysqld not compiled with ndbcluster"); + $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster_slave= 1; + return; + } + $opt_ndbcluster_supported= 1; + mtr_report("Using ndbcluster when necessary, mysqld supports it"); return; } +sub ndbcluster_start_install ($) { + my $cluster= shift; + + if ( $opt_skip_ndbcluster or $glob_use_running_ndbcluster ) + { + return 0; + } + + mtr_report("Installing $cluster->{'name'} Cluster"); + + mkdir($cluster->{'data_dir'}); + + # Create a config file from template + my $ndb_no_ord=512; + my $ndb_no_attr=2048; + my $ndb_con_op=105000; + my $ndb_dmem="80M"; + my $ndb_imem="24M"; + my $ndb_pbmem="32M"; + my $nodes= $cluster->{'nodes'}; + my $ndb_host= "localhost"; + my $ndb_diskless= 0; + + if (!$opt_bench) + { + # Use a smaller configuration + $ndb_no_ord=32; + $ndb_con_op=5000; + $ndb_dmem="20M"; + $ndb_imem="1M"; + $ndb_pbmem="4M"; + } + + my $config_file_template= "ndb/ndb_config_${nodes}_node.ini"; + my $config_file= "$cluster->{'data_dir'}/config.ini"; + + open(IN, $config_file_template) + or mtr_error("Can't open $config_file_template: $!"); + open(OUT, ">", $config_file) + or mtr_error("Can't write to $config_file: $!"); + while () + { + chomp; + + s/CHOOSE_MaxNoOfAttributes/$ndb_no_attr/; + s/CHOOSE_MaxNoOfOrderedIndexes/$ndb_no_ord/; + s/CHOOSE_MaxNoOfConcurrentOperations/$ndb_con_op/; + s/CHOOSE_DataMemory/$ndb_dmem/; + s/CHOOSE_IndexMemory/$ndb_imem/; + s/CHOOSE_Diskless/$ndb_diskless/; + s/CHOOSE_HOSTNAME_.*/$ndb_host/; + s/CHOOSE_FILESYSTEM/$cluster->{'data_dir'}/; + s/CHOOSE_PORT_MGM/$cluster->{'port'}/; + s/CHOOSE_DiskPageBufferMemory/$ndb_pbmem/; + + print OUT "$_ \n"; + } + close OUT; + close IN; + + + # Start cluster with "--initial" + + ndbcluster_start($cluster, "--initial"); + + return 0; +} + + +sub ndbcluster_wait_started($$){ + my $cluster= shift; + my $ndb_waiter_extra_opt= shift; + my $path_waiter_log= "$cluster->{'data_dir'}/ndb_waiter.log"; + my $args; + + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--ndb-connectstring=%s", $cluster->{'connect_string'}); + mtr_add_arg($args, "--timeout=60"); + + if ($ndb_waiter_extra_opt) + { + mtr_add_arg($args, "$ndb_waiter_extra_opt"); + } + + # Start the ndb_waiter which will connect to the ndb_mgmd + # and poll it for state of the ndbd's, will return when + # all nodes in the cluster is started + my $res= mtr_run($exe_ndb_waiter, $args, + "", $path_waiter_log, $path_waiter_log, ""); + mtr_verbose("ndbcluster_wait_started, returns: $res") if $res; + return $res; +} + + + +sub mysqld_wait_started($){ + my $mysqld= shift; + + my $res= sleep_until_file_created($mysqld->{'path_pid'}, + $mysqld->{'start_timeout'}, + $mysqld->{'pid'}); + return $res == 0; +} + + +sub ndb_mgmd_wait_started($) { + my ($cluster)= @_; + + my $retries= 100; + while (ndbcluster_wait_started($cluster, "--no-contact") and + $retries) + { + # Millisceond sleep emulated with select + select(undef, undef, undef, (0.1)); + + $retries--; + } + + return $retries == 0; + +} + +sub ndb_mgmd_start ($) { + my $cluster= shift; + + my $args; # Arg vector + my $pid= -1; + + mtr_init_args(\$args); + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--nodaemon"); + mtr_add_arg($args, "--config-file=%s", "$cluster->{'data_dir'}/config.ini"); + + + my $path_ndb_mgmd_log= "$cluster->{'data_dir'}/\l$cluster->{'name'}_ndb_mgmd.log"; + $pid= mtr_spawn($exe_ndb_mgmd, $args, "", + $path_ndb_mgmd_log, + $path_ndb_mgmd_log, + "", + { append_log_file => 1 }); + + # FIXME Should not be needed + # Unfortunately the cluster nodes will fail to start + # if ndb_mgmd has not started properly + if (ndb_mgmd_wait_started($cluster)) + { + mtr_error("Failed to wait for start of ndb_mgmd"); + } + + # Remember pid of ndb_mgmd + $cluster->{'pid'}= $pid; + + mtr_verbose("ndb_mgmd_start, pid: $pid"); + + return $pid; +} + + +sub ndbd_start ($$$) { + my $cluster= shift; + my $idx= shift; + my $extra_args= shift; + + my $args; # Arg vector + my $pid= -1; + + mtr_init_args(\$args); + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--core"); + mtr_add_arg($args, "--ndb-connectstring=%s", "$cluster->{'connect_string'}"); + mtr_add_arg($args, "--character-sets-dir=%s", "$path_charsetsdir"); + mtr_add_arg($args, "--nodaemon"); + mtr_add_arg($args, "$extra_args"); + + my $nodeid= $cluster->{'ndbds'}->[$idx]->{'nodeid'}; + my $path_ndbd_log= "$cluster->{'data_dir'}/ndb_${nodeid}.log"; + $pid= mtr_spawn($exe_ndbd, $args, "", + $path_ndbd_log, + $path_ndbd_log, + "", + { append_log_file => 1 }); + + # Add pid to list of pids for this cluster + $cluster->{'ndbds'}->[$idx]->{'pid'}= $pid; + + # Rememeber options used when starting + $cluster->{'ndbds'}->[$idx]->{'start_extra_args'}= $extra_args; + $cluster->{'ndbds'}->[$idx]->{'idx'}= $idx; + + mtr_verbose("ndbd_start, pid: $pid"); + + return $pid; +} + + +sub ndbcluster_start ($$) { + my $cluster= shift; + my $extra_args= shift; + + mtr_verbose("ndbcluster_start '$cluster->{'name'}'"); + + if ( $glob_use_running_ndbcluster ) + { + return 0; + } + + if ( $cluster->{'pid'} ) + { + mtr_error("Cluster '$cluster->{'name'}' already started"); + } + + ndb_mgmd_start($cluster); + + for ( my $idx= 0; $idx < $cluster->{'nodes'}; $idx++ ) + { + ndbd_start($cluster, $idx, $extra_args); + } + + return 0; +} + + +sub rm_ndbcluster_tables ($) { + my $dir= shift; + foreach my $bin ( glob("$dir/cluster/apply_status*"), + glob("$dir/cluster/schema*") ) + { + unlink($bin); + } +} + + ############################################################################## # # Run the benchmark suite @@ -1323,9 +2143,9 @@ sub run_benchmarks ($) { my $args; - if ( ! $glob_use_embedded_server and ! $opt_local_master ) + if ( ! $glob_use_embedded_server ) { - $master->[0]->{'pid'}= mysqld_start('master',0,[],[]); + mysqld_start($master->[0],[],[]); if ( ! $master->[0]->{'pid'} ) { mtr_error("Can't start the mysqld server"); @@ -1334,7 +2154,7 @@ sub run_benchmarks ($) { mtr_init_args(\$args); - mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'}); + mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); mtr_add_arg($args, "--user=%s", $opt_user); if ( $opt_small_bench ) @@ -1348,10 +2168,8 @@ sub run_benchmarks ($) { mtr_add_arg($args, "--create-options=TYPE=ndb"); } - my $benchdir= "$glob_basedir/sql-bench"; - chdir($benchdir); # FIXME check error - - # FIXME write shorter.... + chdir($glob_mysql_bench_dir) + or mtr_error("Couldn't chdir to '$glob_mysql_bench_dir': $!"); if ( ! $benchmark ) { @@ -1384,29 +2202,26 @@ sub run_benchmarks ($) { # ############################################################################## -# FIXME how to specify several suites to run? Comma separated list? - -sub run_tests () { - run_suite($opt_suite); -} - sub run_suite () { - my $suite= shift; + my ($suite, $tests)= @_; mtr_print_thick_line(); - mtr_report("Finding Tests in the '$suite' suite"); - mtr_timer_start($glob_timers,"suite", 60 * $opt_suite_timeout); - my $tests= collect_test_cases($suite); - mtr_report("Starting Tests in the '$suite' suite"); + mtr_report_tests_not_skipped_though_disabled($tests); + mtr_print_header(); foreach my $tinfo ( @$tests ) { + if (run_testcase_check_skip_test($tinfo)) + { + next; + } + mtr_timer_start($glob_timers,"testcase", 60 * $opt_testcase_timeout); run_testcase($tinfo); mtr_timer_stop($glob_timers,"testcase"); @@ -1414,10 +2229,11 @@ sub run_suite () { mtr_print_line(); - if ( ! $opt_gdb and ! $glob_use_running_server and - ! $opt_ddd and ! $glob_use_embedded_server ) + if ( ! $glob_debugger and + ! $glob_use_running_server and + ! $glob_use_embedded_server ) { - stop_masters_slaves(); + stop_all_servers(); } if ( $opt_gcov ) @@ -1431,6 +2247,8 @@ sub run_suite () { mtr_report_stats($tests); +# Look for testname.warning files if --do-test= + mtr_timer_stop($glob_timers,"suite"); } @@ -1441,26 +2259,99 @@ sub run_suite () { # ############################################################################## +sub initialize_servers () { + if ( ! $glob_use_running_server ) + { + kill_running_server(); + + unless ( $opt_start_dirty ) + { + cleanup_stale_files(); + mysql_install_db(); + if ( $opt_force ) + { + save_installed_db(); + } + } + check_running_as_root(); + } +} + sub mysql_install_db () { - # FIXME not exactly true I think, needs improvements install_db('master', $master->[0]->{'path_myddir'}); - install_db('master', $master->[1]->{'path_myddir'}); - install_db('slave', $slave->[0]->{'path_myddir'}); - install_db('slave', $slave->[1]->{'path_myddir'}); - install_db('slave', $slave->[2]->{'path_myddir'}); - if ( ndbcluster_install() ) + # FIXME check if testcase really is using second master + copy_install_db('master', $master->[1]->{'path_myddir'}); + + # Install the number of slave databses needed + for (my $idx= 0; $idx < $max_slave_num; $idx++) { - # failed to install, disable usage but flag that its no ok - $opt_with_ndbcluster= 0; - $flag_ndb_status_ok= 0; + copy_install_db("slave".($idx+1), $slave->[$idx]->{'path_myddir'}); } + if ( ! $opt_skip_im ) + { + im_prepare_env($instance_manager); + } + + my $cluster_started_ok= 1; # Assume it can be started + + if (ndbcluster_start_install($clusters->[0]) || + $max_slave_num && ndbcluster_start_install($clusters->[1])) + { + mtr_warning("Failed to start install of cluster"); + $cluster_started_ok= 0; + } + + foreach my $cluster (@{$clusters}) + { + + next if !$cluster->{'pid'}; + + $cluster->{'installed_ok'}= 1; # Assume install suceeds + + if (ndbcluster_wait_started($cluster, "")) + { + # failed to install, disable usage and flag that its no ok + mtr_report("ndbcluster_install of $cluster->{'name'} failed"); + $cluster->{"installed_ok"}= 0; + + $cluster_started_ok= 0; + } + } + + if ( ! $cluster_started_ok ) + { + if ( $opt_force) + { + # Continue without cluster + } + else + { + mtr_error("To continue, re-run with '--force'."); + } + } + + # Stop clusters... + stop_all_servers(); + return 0; } +sub copy_install_db ($$) { + my $type= shift; + my $data_dir= shift; + + mtr_report("Installing \u$type Database"); + + # Just copy the installed db from first master + mtr_copy_dir($master->[0]->{'path_myddir'}, $data_dir); + +} + + sub install_db ($$) { my $type= shift; my $data_dir= shift; @@ -1469,7 +2360,7 @@ sub install_db ($$) { my $init_db_sql_tmp= "/tmp/init_db.sql$$"; my $args; - mtr_report("Installing \u$type Databases"); + mtr_report("Installing \u$type Database"); open(IN, $init_db_sql) or mtr_error("Can't open $init_db_sql: $!"); @@ -1505,16 +2396,29 @@ sub install_db ($$) { mtr_add_arg($args, "--datadir=%s", $data_dir); mtr_add_arg($args, "--skip-innodb"); mtr_add_arg($args, "--skip-ndbcluster"); - mtr_add_arg($args, "--skip-bdb"); + mtr_add_arg($args, "--tmpdir=."); - if ( ! $opt_netware ) + if ( $opt_debug ) + { + mtr_add_arg($args, "--debug=d:t:i:A,%s/log/bootstrap_%s.trace", + $path_vardir_trace, $type); + } + + if ( ! $glob_netware ) { mtr_add_arg($args, "--language=%s", $path_language); mtr_add_arg($args, "--character-sets-dir=%s", $path_charsetsdir); } + # Log bootstrap command + my $path_bootstrap_log= "$opt_vardir/log/bootstrap.log"; + mtr_tofile($path_bootstrap_log, + "$exe_mysqld " . join(" ", @$args) . "\n"); + if ( mtr_run($exe_mysqld, $args, $init_db_sql_tmp, - $path_manager_log, $path_manager_log, "") != 0 ) + $path_bootstrap_log, $path_bootstrap_log, + "", { append_log_file => 1 }) != 0 ) + { unlink($init_db_sql_tmp); mtr_error("Error executing mysqld --bootstrap\n" . @@ -1524,6 +2428,196 @@ sub install_db ($$) { } +sub im_prepare_env($) { + my $instance_manager = shift; + + im_create_passwd_file($instance_manager); + im_prepare_data_dir($instance_manager); +} + + +sub im_create_passwd_file($) { + my $instance_manager = shift; + + my $pwd_file_path = $instance_manager->{'password_file'}; + + mtr_report("Creating IM password file ($pwd_file_path)"); + + open(OUT, ">", $pwd_file_path) + or mtr_error("Can't write to $pwd_file_path: $!"); + + print OUT $instance_manager->{'admin_login'}, ":", + $instance_manager->{'admin_sha1'}, "\n"; + + close(OUT); +} + + +sub im_create_defaults_file($) { + my $instance_manager = shift; + + my $defaults_file = $instance_manager->{'defaults_file'}; + + open(OUT, ">", $defaults_file) + or mtr_error("Can't write to $defaults_file: $!"); + + print OUT <{path_pid} +angel-pid-file = $instance_manager->{path_angel_pid} +socket = $instance_manager->{path_sock} +port = $instance_manager->{port} +password-file = $instance_manager->{password_file} +default-mysqld-path = $exe_mysqld + +EOF +; + + foreach my $instance (@{$instance_manager->{'instances'}}) + { + my $server_id = $instance->{'server_id'}; + + print OUT <{path_sock} +pid-file = $instance->{path_pid} +port = $instance->{port} +datadir = $instance->{path_datadir} +log = $instance->{path_datadir}/mysqld$server_id.log +log-error = $instance->{path_datadir}/mysqld$server_id.err.log +log-slow-queries = $instance->{path_datadir}/mysqld$server_id.slow.log +language = $path_language +character-sets-dir = $path_charsetsdir +basedir = $path_my_basedir +server_id = $server_id +skip-stack-trace +skip-innodb +skip-ndbcluster +EOF +; + + print OUT "nonguarded\n" if $instance->{'nonguarded'}; + print OUT "log-output=FILE\n" if $instance->{'old_log_format'}; + print OUT "\n"; + } + + close(OUT); +} + + +sub im_prepare_data_dir($) { + my $instance_manager = shift; + + foreach my $instance (@{$instance_manager->{'instances'}}) + { + copy_install_db( + 'im_mysqld_' . $instance->{'server_id'}, + $instance->{'path_datadir'}); + } +} + + + +# +# Restore snapshot of the installed slave databases +# if the snapshot exists +# +sub restore_slave_databases ($) { + my ($num_slaves)= @_; + + if ( -d $path_snapshot) + { + for (my $idx= 0; $idx < $num_slaves; $idx++) + { + my $data_dir= $slave->[$idx]->{'path_myddir'}; + my $name= basename($data_dir); + rmtree($data_dir); + mtr_copy_dir("$path_snapshot/$name", $data_dir); + } + } +} + + +sub run_testcase_check_skip_test($) +{ + my ($tinfo)= @_; + + # ---------------------------------------------------------------------- + # If marked to skip, just print out and return. + # Note that a test case not marked as 'skip' can still be + # skipped later, because of the test case itself in cooperation + # with the mysqltest program tells us so. + # ---------------------------------------------------------------------- + + if ( $tinfo->{'skip'} ) + { + mtr_report_test_name($tinfo); + mtr_report_test_skipped($tinfo); + return 1; + } + + # If test needs cluster, check that master installed ok + if ( $tinfo->{'ndb_test'} and !$clusters->[0]->{'installed_ok'} ) + { + mtr_report_test_name($tinfo); + mtr_report_test_failed($tinfo); + return 1; + } + + # If test needs slave cluster, check that it installed ok + if ( $tinfo->{'ndb_test'} and $tinfo->{'slave_num'} and + !$clusters->[1]->{'installed_ok'} ) + { + mtr_report_test_name($tinfo); + mtr_report_test_failed($tinfo); + return 1; + } + + return 0; +} + + +sub do_before_run_mysqltest($) +{ + my $tinfo= shift; + my $tname= $tinfo->{'name'}; + + # Remove old reject file + if ( $opt_suite eq "main" ) + { + unlink("r/$tname.reject"); + } + else + { + unlink("suite/$opt_suite/r/$tname.reject"); + } + + mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are + + # output current test to ndbcluster log file to enable diagnostics + mtr_tofile($path_ndb_testrun_log,"CURRENT TEST $tname\n"); + + mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + if ( $master->[1]->{'pid'} ) + { + mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + } +} + +sub do_after_run_mysqltest($) +{ + my $tinfo= shift; + my $tname= $tinfo->{'name'}; + + # Save info from this testcase run to mysqltest.log + mtr_appendfile_to_file($path_timefile, $path_mysqltest_log) + if -f $path_timefile; + mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n"); +} + + ############################################################################## # # Run a single test case @@ -1543,231 +2637,34 @@ sub install_db ($$) { sub run_testcase ($) { my $tinfo= shift; - my $tname= $tinfo->{'name'}; + my $master_restart= run_testcase_need_master_restart($tinfo); + my $slave_restart= run_testcase_need_slave_restart($tinfo); - mtr_tonewfile($opt_current_test,"$tname\n"); # Always tell where we are - - # output current test to ndbcluster log file to enable diagnostics - mtr_tofile($file_ndb_testrun_log,"CURRENT TEST $tname\n"); - - # ---------------------------------------------------------------------- - # If marked to skip, just print out and return. - # Note that a test case not marked as 'skip' can still be - # skipped later, because of the test case itself in cooperation - # with the mysqltest program tells us so. - # ---------------------------------------------------------------------- - - if ( $tinfo->{'skip'} ) + if ($master_restart or $slave_restart) { - mtr_report_test_name($tinfo); - mtr_report_test_skipped($tinfo); - return; + run_testcase_stop_servers($tinfo, $master_restart, $slave_restart); + } + my $died= mtr_record_dead_children(); + if ($died or $master_restart or $slave_restart) + { + run_testcase_start_servers($tinfo); } # ---------------------------------------------------------------------- - # If not using a running servers we may need to stop and restart. - # We restart in the case we have initiation scripts, server options - # etc to run. But we also restart again after the test first restart - # and test is run, to get back to normal server settings. - # - # To make the code a bit more clean, we actually only stop servers - # here, and mark this to be done. Then a generic "start" part will - # start up the needed servers again. + # If --start-and-exit or --start-dirty given, stop here to let user manually + # run tests # ---------------------------------------------------------------------- - - if ( ! $glob_use_running_server and ! $glob_use_embedded_server ) - { - # We try to find out if we are to restart the server - my $do_restart= 0; # Assumes we don't have to - - if ( $tinfo->{'master_sh'} ) - { - $do_restart= 1; # Always restart if script to run - } - elsif ( $tinfo->{'ndb_test'} and $master->[0]->{'ndbcluster'} == 1 ) - { - $do_restart= 1; # Restart with cluster - # print "Restarting because cluster need to be enabled\n"; - } - elsif ($tinfo->{'ndb_test'} == 0 and $master->[0]->{'ndbcluster'} == 0) - { - $do_restart= 1; # Restart without cluster - # print "Restarting because cluster need to be disabled\n"; - } - elsif ( $master->[0]->{'running_master_is_special'} and - $master->[0]->{'running_master_is_special'}->{'timezone'} eq - $tinfo->{'timezone'} and - mtr_same_opts($master->[0]->{'running_master_is_special'}->{'master_opt'}, - $tinfo->{'master_opt'}) ) - { - # If running master was started with special settings, but - # the current test requuires the same ones, we *don't* restart. - $do_restart= 0; - } - elsif ( $tinfo->{'master_restart'} or - $master->[0]->{'running_master_is_special'} ) - { - $do_restart= 1; - } - - if ( $do_restart ) - { - stop_masters(); - delete $master->[0]->{'running_master_is_special'}; # Forget history - } - - # ---------------------------------------------------------------------- - # Always terminate all slaves, if any. Else we may have useless - # reconnection attempts and error messages in case the slave and - # master servers restart. - # ---------------------------------------------------------------------- - - stop_slaves(); - } - - # ---------------------------------------------------------------------- - # Prepare to start masters. Even if we use embedded, we want to run - # the preparation. - # ---------------------------------------------------------------------- - - $ENV{'TZ'}= $tinfo->{'timezone'}; - - mtr_report_test_name($tinfo); - - mtr_tofile($master->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - -# FIXME test cases that depend on each other, prevent this from -# being at this location. -# do_before_start_master($tname,$tinfo->{'master_sh'}); - - # ---------------------------------------------------------------------- - # If any mysqld servers running died, we have to know - # ---------------------------------------------------------------------- - - mtr_record_dead_children(); - - # ---------------------------------------------------------------------- - # Start masters - # ---------------------------------------------------------------------- - - if ( ! $glob_use_running_server and ! $glob_use_embedded_server ) - { - # FIXME give the args to the embedded server?! - # FIXME what does $opt_local_master mean?! - # FIXME split up start and check that started so that can do - # starts in parallel, masters and slaves at the same time. - - if ( ! $opt_local_master ) - { - if ( $master->[0]->{'ndbcluster'} && $tinfo->{'ndb_test'}) - { - $master->[0]->{'ndbcluster'}= ndbcluster_start(); - if ( $master->[0]->{'ndbcluster'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - if ( ! $master->[0]->{'pid'} ) - { - # FIXME not correct location for do_before_start_master() - do_before_start_master($tname,$tinfo->{'master_sh'}); - - # Save skip_ndbcluster - my $save_opt_skip_ndbcluster= $opt_skip_ndbcluster; - if (!$tinfo->{'ndb_test'}) - { - # Modify skip_ndbcluster so cluster is skipped for this - # and subsequent testcases(until we find one that does not cluster) - $opt_skip_ndbcluster= 1; - } - - $master->[0]->{'pid'}= - mysqld_start('master',0,$tinfo->{'master_opt'},[]); - - # Restore skip_ndbcluster - $opt_skip_ndbcluster= $save_opt_skip_ndbcluster; - - if ( ! $master->[0]->{'pid'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - if ( $opt_with_ndbcluster and ! $master->[1]->{'pid'} ) - { - # Test needs cluster, start an extra mysqld connected to cluster - $master->[1]->{'pid'}= - mysqld_start('master',1,$tinfo->{'master_opt'},[]); - if ( ! $master->[1]->{'pid'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - - if ( $tinfo->{'master_restart'} ) - { - # Save this test case information, so next can examine it - $master->[0]->{'running_master_is_special'}= $tinfo; - } - } - - # ---------------------------------------------------------------------- - # Start slaves - if needed - # ---------------------------------------------------------------------- - - if ( $tinfo->{'slave_num'} ) - { - mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); - - do_before_start_slave($tname,$tinfo->{'slave_sh'}); - - for ( my $idx= 0; $idx < $tinfo->{'slave_num'}; $idx++ ) - { - if ( ! $slave->[$idx]->{'pid'} ) - { - $slave->[$idx]->{'pid'}= - mysqld_start('slave',$idx, - $tinfo->{'slave_opt'}, $tinfo->{'slave_mi'}); - if ( ! $slave->[$idx]->{'pid'} ) - { - report_failure_and_restart($tinfo); - return; - } - } - } - } - } - - # ---------------------------------------------------------------------- - # If --start-and-exit given, stop here to let user manually run tests - # ---------------------------------------------------------------------- - - if ( $opt_start_and_exit ) + if ( $opt_start_and_exit or $opt_start_dirty ) { mtr_report("\nServers started, exiting"); exit(0); } - # ---------------------------------------------------------------------- - # Run the test case - # ---------------------------------------------------------------------- - { - # remove the old reject file - if ( $opt_suite eq "main" ) - { - unlink("r/$tname.reject"); - } - else - { - unlink("suite/$opt_suite/r/$tname.reject"); - } - unlink($path_timefile); + do_before_run_mysqltest($tinfo); my $res= run_mysqltest($tinfo); - + mtr_report_test_name($tinfo); if ( $res == 0 ) { mtr_report_test_passed($tinfo); @@ -1775,6 +2672,12 @@ sub run_testcase ($) { elsif ( $res == 62 ) { # Testcase itself tell us to skip this one + + # Try to get reason from mysqltest.log + my $last_line= mtr_lastlinefromfile($path_timefile) if -f $path_timefile; + my $reason= mtr_match_prefix($last_line, "reason: "); + $tinfo->{'comment'}= + defined $reason ? $reason : "Detected by testcase(reason unknown) "; mtr_report_test_skipped($tinfo); } elsif ( $res == 63 ) @@ -1791,38 +2694,128 @@ sub run_testcase ($) { "mysqltest returned unexpected code $res, " . "it has probably crashed"); } + report_failure_and_restart($tinfo); } + + do_after_run_mysqltest($tinfo); + } + + # ---------------------------------------------------------------------- + # Stop Instance Manager if we are processing an IM-test case. + # ---------------------------------------------------------------------- + + if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' ) + { + unless ( mtr_im_stop($instance_manager, $tinfo->{'name'}) ) + { + mtr_error("Failed to stop Instance Manager.") + } } } +# +# Save a snapshot of the installed test db(s) +# I.e take a snapshot of the var/ dir +# +sub save_installed_db () { + + mtr_report("Saving snapshot of installed databases"); + rmtree($path_snapshot); + + foreach my $data_dir (@data_dir_lst) + { + my $name= basename($data_dir); + mtr_copy_dir("$data_dir", "$path_snapshot/$name"); + } +} + + +# +# Save any interesting files in the data_dir +# before the data dir is removed. +# +sub save_files_before_restore($$) { + my $test_name= shift; + my $data_dir= shift; + my $save_name= "$opt_vardir/log/$test_name"; + + # Look for core files + foreach my $core_file ( glob("$data_dir/core*") ) + { + my $core_name= basename($core_file); + mtr_report("Saving $core_name"); + mkdir($save_name) if ! -d $save_name; + rename("$core_file", "$save_name/$core_name"); + } +} + + +# +# Restore snapshot of the installed test db(s) +# if the snapshot exists +# +sub restore_installed_db ($) { + my $test_name= shift; + + if ( -d $path_snapshot) + { + mtr_report("Restoring snapshot of databases"); + + foreach my $data_dir (@data_dir_lst) + { + my $name= basename($data_dir); + save_files_before_restore($test_name, $data_dir); + rmtree("$data_dir"); + mtr_copy_dir("$path_snapshot/$name", "$data_dir"); + } + + # Remove the ndb_*_fs dirs for all ndbd nodes + # forcing a clean start of ndb + foreach my $cluster (@{$clusters}) + { + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + rmtree("$ndbd->{'path_fs'}" ); + } + } + } + else + { + # No snapshot existed + mtr_error("No snapshot existed"); + } +} + sub report_failure_and_restart ($) { my $tinfo= shift; mtr_report_test_failed($tinfo); mtr_show_failed_diff($tinfo->{'name'}); print "\n"; - if ( ! $opt_force ) + if ( $opt_force ) { - my $test_mode= join(" ", @::glob_test_mode) || "default"; - print "Aborting: $tinfo->{'name'} failed in $test_mode mode. "; - print "To continue, re-run with '--force'.\n"; - if ( ! $opt_gdb and ! $glob_use_running_server and - ! $opt_ddd and ! $glob_use_embedded_server ) - { - stop_masters_slaves(); - } - mtr_exit(1); + # Stop all servers that are known to be running + stop_all_servers(); + + # Restore the snapshot of the installed test db + restore_installed_db($tinfo->{'name'}); + print "Resuming Tests\n\n"; + return; } - # FIXME always terminate on failure?! - if ( ! $opt_gdb and ! $glob_use_running_server and - ! $opt_ddd and ! $glob_use_embedded_server ) + my $test_mode= join(" ", @::glob_test_mode) || "default"; + print "Aborting: $tinfo->{'name'} failed in $test_mode mode. "; + print "To continue, re-run with '--force'.\n"; + if ( ! $glob_debugger and + ! $glob_use_running_server and + ! $glob_use_embedded_server ) { - stop_masters_slaves(); + stop_all_servers(); } - print "Resuming Tests\n\n"; + mtr_exit(1); + } @@ -1832,9 +2825,9 @@ sub report_failure_and_restart ($) { # ############################################################################## + # The embedded server needs the cleanup so we do some of the start work # but stop before actually running mysqld or anything. - sub do_before_start_master ($$) { my $tname= shift; my $init_script= shift; @@ -1867,13 +2860,14 @@ sub do_before_start_master ($$) { if ( $ret != 0 ) { # FIXME rewrite those scripts to return 0 if successful -# mtr_warning("$init_script exited with code $ret"); + # mtr_warning("$init_script exited with code $ret"); } } # for gcov FIXME needed? If so we need more absolute paths -# chdir($glob_basedir); + # chdir($glob_basedir); } + sub do_before_start_slave ($$) { my $tname= shift; my $init_script= shift; @@ -1901,7 +2895,7 @@ sub do_before_start_slave ($$) { if ( $ret != 0 ) { # FIXME rewrite those scripts to return 0 if successful -# mtr_warning("$init_script exited with code $ret"); + # mtr_warning("$init_script exited with code $ret"); } } @@ -1911,9 +2905,10 @@ sub do_before_start_slave ($$) { } } + sub mysqld_arguments ($$$$$) { my $args= shift; - my $type= shift; # master/slave/bootstrap + my $type= shift; my $idx= shift; my $extra_opt= shift; my $slave_master_info= shift; @@ -1921,7 +2916,7 @@ sub mysqld_arguments ($$$$$) { my $sidx= ""; # Index as string, 0 is empty string if ( $idx > 0 ) { - $sidx= sprintf("%d", $idx); # sprintf not needed in Perl for this + $sidx= "$idx"; } my $prefix= ""; # If mysqltest server arg @@ -1937,15 +2932,19 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--console", $prefix); mtr_add_arg($args, "%s--basedir=%s", $prefix, $path_my_basedir); mtr_add_arg($args, "%s--character-sets-dir=%s", $prefix, $path_charsetsdir); - mtr_add_arg($args, "%s--core", $prefix); + + if ( $mysql_version_id >= 50000 ) + { + mtr_add_arg($args, "%s--log-bin-trust-function-creators", $prefix); + } + mtr_add_arg($args, "%s--default-character-set=latin1", $prefix); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); - if ( defined $opt_valgrind_mysqld ) + if ( $opt_valgrind_mysqld ) { mtr_add_arg($args, "%s--skip-safemalloc", $prefix); - mtr_add_arg($args, "%s--skip-bdb", $prefix); } my $pidfile; @@ -1954,29 +2953,41 @@ sub mysqld_arguments ($$$$$) { { my $id= $idx > 0 ? $idx + 101 : 1; - mtr_add_arg($args, "%s--log-bin=%s/log/master-bin%s", $prefix, - $opt_vardir, $sidx); + if (! $opt_skip_master_binlog) + { + mtr_add_arg($args, "%s--log-bin=%s/log/master-bin%s", $prefix, + $opt_vardir, $sidx); + } mtr_add_arg($args, "%s--pid-file=%s", $prefix, - $master->[$idx]->{'path_mypid'}); + $master->[$idx]->{'path_pid'}); mtr_add_arg($args, "%s--port=%d", $prefix, - $master->[$idx]->{'path_myport'}); + $master->[$idx]->{'port'}); mtr_add_arg($args, "%s--server-id=%d", $prefix, $id); mtr_add_arg($args, "%s--socket=%s", $prefix, - $master->[$idx]->{'path_mysock'}); - mtr_add_arg($args, "%s--innodb_data_file_path=ibdata1:50M", $prefix); + $master->[$idx]->{'path_sock'}); + mtr_add_arg($args, "%s--innodb_data_file_path=ibdata1:10M:autoextend", $prefix); mtr_add_arg($args, "%s--local-infile", $prefix); mtr_add_arg($args, "%s--datadir=%s", $prefix, $master->[$idx]->{'path_myddir'}); - if ( $idx > 0 ) + if ( $idx > 0 or !$use_innodb) { mtr_add_arg($args, "%s--skip-innodb", $prefix); } - if ( $opt_skip_ndbcluster ) + my $cluster= $clusters->[$master->[$idx]->{'cluster'}]; + if ( $opt_skip_ndbcluster || + !$cluster->{'pid'}) { mtr_add_arg($args, "%s--skip-ndbcluster", $prefix); } + else + { + mtr_add_arg($args, "%s--ndbcluster", $prefix); + mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, + $cluster->{'connect_string'}); + mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + } } if ( $type eq 'slave' ) @@ -1986,25 +2997,26 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--datadir=%s", $prefix, $slave->[$idx]->{'path_myddir'}); - # FIXME slave get this option twice?! - mtr_add_arg($args, "%s--exit-info=256", $prefix); mtr_add_arg($args, "%s--init-rpl-role=slave", $prefix); - mtr_add_arg($args, "%s--log-bin=%s/log/slave%s-bin", $prefix, - $opt_vardir, $sidx); # FIXME use own dir for binlogs - mtr_add_arg($args, "%s--log-slave-updates", $prefix); - # FIXME option duplicated for slave + if (! $opt_skip_slave_binlog) + { + mtr_add_arg($args, "%s--log-bin=%s/log/slave%s-bin", $prefix, + $opt_vardir, $sidx); # FIXME use own dir for binlogs + mtr_add_arg($args, "%s--log-slave-updates", $prefix); + } + mtr_add_arg($args, "%s--log=%s", $prefix, $slave->[$idx]->{'path_mylog'}); mtr_add_arg($args, "%s--master-retry-count=10", $prefix); mtr_add_arg($args, "%s--pid-file=%s", $prefix, - $slave->[$idx]->{'path_mypid'}); + $slave->[$idx]->{'path_pid'}); mtr_add_arg($args, "%s--port=%d", $prefix, - $slave->[$idx]->{'path_myport'}); + $slave->[$idx]->{'port'}); mtr_add_arg($args, "%s--relay-log=%s/log/slave%s-relay-bin", $prefix, $opt_vardir, $sidx); mtr_add_arg($args, "%s--report-host=127.0.0.1", $prefix); mtr_add_arg($args, "%s--report-port=%d", $prefix, - $slave->[$idx]->{'path_myport'}); + $slave->[$idx]->{'port'}); mtr_add_arg($args, "%s--report-user=root", $prefix); mtr_add_arg($args, "%s--skip-innodb", $prefix); mtr_add_arg($args, "%s--skip-ndbcluster", $prefix); @@ -2014,9 +3026,9 @@ sub mysqld_arguments ($$$$$) { # on the server. The path need to have constant length otherwise # test results will vary, thus a relative path is used. mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix, - $path_slave_load_tmpdir); + "../tmp"); mtr_add_arg($args, "%s--socket=%s", $prefix, - $slave->[$idx]->{'path_mysock'}); + $slave->[$idx]->{'path_sock'}); mtr_add_arg($args, "%s--set-variable=slave_net_timeout=10", $prefix); if ( @$slave_master_info ) @@ -2033,10 +3045,24 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--master-host=127.0.0.1", $prefix); mtr_add_arg($args, "%s--master-password=", $prefix); mtr_add_arg($args, "%s--master-port=%d", $prefix, - $master->[0]->{'path_myport'}); # First master + $master->[0]->{'port'}); # First master mtr_add_arg($args, "%s--server-id=%d", $prefix, $slave_server_id); mtr_add_arg($args, "%s--rpl-recovery-rank=%d", $prefix, $slave_rpl_rank); } + + if ( $opt_skip_ndbcluster_slave || + $slave->[$idx]->{'cluster'} == -1 || + !$clusters->[$slave->[$idx]->{'cluster'}]->{'pid'} ) + { + mtr_add_arg($args, "%s--skip-ndbcluster", $prefix); + } + else + { + mtr_add_arg($args, "%s--ndbcluster", $prefix); + mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, + $clusters->[$slave->[$idx]->{'cluster'}]->{'connect_string'}); + mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + } } # end slave if ( $opt_debug ) @@ -2044,28 +3070,21 @@ sub mysqld_arguments ($$$$$) { if ( $type eq 'master' ) { mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/master%s.trace", - $prefix, $opt_vardir, $sidx); + $prefix, $path_vardir_trace, $sidx); } if ( $type eq 'slave' ) { mtr_add_arg($args, "%s--debug=d:t:i:A,%s/log/slave%s.trace", - $prefix, $opt_vardir, $sidx); + $prefix, $path_vardir_trace, $sidx); } } - if ( $opt_with_ndbcluster && !$opt_skip_ndbcluster && $type eq 'master') - { - mtr_add_arg($args, "%s--ndbcluster", $prefix); - mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, - $opt_ndbconnectstring); - } - # FIXME always set nowdays??? SMALL_SERVER mtr_add_arg($args, "%s--key_buffer_size=1M", $prefix); mtr_add_arg($args, "%s--sort_buffer=256K", $prefix); mtr_add_arg($args, "%s--max_heap_table_size=1M", $prefix); - if ( $opt_with_openssl ) + if ( $opt_ssl_supported ) { mtr_add_arg($args, "%s--ssl-ca=%s/std_data/cacert.pem", $prefix, $glob_mysql_test_dir); @@ -2080,7 +3099,8 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--log-warnings", $prefix); } - if ( $opt_gdb or $opt_client_gdb or $opt_manual_gdb or $opt_ddd) + # Indicate to "mysqld" it will be debugged in debugger + if ( $glob_debugger ) { mtr_add_arg($args, "%s--gdb", $prefix); } @@ -2093,27 +3113,22 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--user=root", $prefix); } - if ( $type eq 'master' ) - { - - if ( ! $opt_old_master ) - { - mtr_add_arg($args, "%s--rpl-recovery-rank=1", $prefix); - mtr_add_arg($args, "%s--init-rpl-role=master", $prefix); - } - - # FIXME strange,..... - # FIXME MYSQL_MYPORT is not set anythere?! - if ( $opt_local_master ) - { - mtr_add_arg($args, "%s--host=127.0.0.1", $prefix); - mtr_add_arg($args, "%s--port=%s", $prefix, $ENV{'MYSQL_MYPORT'}); - } - } - + my $found_skip_core= 0; foreach my $arg ( @opt_extra_mysqld_opt, @$extra_opt ) { - mtr_add_arg($args, "%s%s", $prefix, $arg); + # Allow --skip-core-file to be set in master.opt file + if ($arg eq "--skip-core-file") + { + $found_skip_core= 1; + } + else + { + mtr_add_arg($args, "%s%s", $prefix, $arg); + } + } + if ( !$found_skip_core ) + { + mtr_add_arg($args, "%s%s", $prefix, "--core-file"); } if ( $opt_bench ) @@ -2123,7 +3138,6 @@ sub mysqld_arguments ($$$$$) { } elsif ( $type eq 'master' ) { - mtr_add_arg($args, "%s--exit-info=256", $prefix); mtr_add_arg($args, "%s--open-files-limit=1024", $prefix); mtr_add_arg($args, "%s--log=%s", $prefix, $master->[0]->{'path_mylog'}); } @@ -2131,14 +3145,6 @@ sub mysqld_arguments ($$$$$) { return $args; } -# FIXME -# if ( $type eq 'master' and $glob_use_embedded_server ) -# { -# # Add a -A to each argument to pass it to embedded server -# my @mysqltest_opt= map {("-A",$_)} @args; -# $opt_extra_mysqltest_opt= \@mysqltest_opt; -# return; -# } ############################################################################## # @@ -2146,15 +3152,18 @@ sub mysqld_arguments ($$$$$) { # ############################################################################## -sub mysqld_start ($$$$) { - my $type= shift; # master/slave/bootstrap - my $idx= shift; +sub mysqld_start ($$$) { + my $mysqld= shift; my $extra_opt= shift; my $slave_master_info= shift; my $args; # Arg vector my $exe; - my $pid; + my $pid= -1; + my $wait_for_pid_file= 1; + + my $type= $mysqld->{'type'}; + my $idx= $mysqld->{'idx'}; if ( $type eq 'master' ) { @@ -2166,214 +3175,682 @@ sub mysqld_start ($$$$) { } else { - $exe= $exe_mysqld; + mtr_error("Unknown 'type' \"$type\" passed to mysqld_start"); } mtr_init_args(\$args); - if ( defined $opt_valgrind_mysqld ) + if ( $opt_valgrind_mysqld ) { valgrind_arguments($args, \$exe); } mysqld_arguments($args,$type,$idx,$extra_opt,$slave_master_info); - if ( $type eq 'master' ) + if ( $opt_gdb || $opt_manual_gdb) { - if ( $pid= mtr_spawn($exe, $args, "", - $master->[$idx]->{'path_myerr'}, - $master->[$idx]->{'path_myerr'}, - "", - { append_log_file => 1 }) ) + gdb_arguments(\$args, \$exe, "$type"."_$idx"); + } + elsif ( $opt_ddd || $opt_manual_ddd ) + { + ddd_arguments(\$args, \$exe, "$type"."_$idx"); + } + elsif ( $opt_debugger ) + { + debugger_arguments(\$args, \$exe, "$type"."_$idx"); + } + elsif ( $opt_manual_debug ) + { + print "\nStart $type in your debugger\n" . + "dir: $glob_mysql_test_dir\n" . + "exe: $exe\n" . + "args: " . join(" ", @$args) . "\n\n" . + "Waiting ....\n"; + + # Indicate the exe should not be started + $exe= undef; + } + else + { + # Default to not wait until pid file has been created + $wait_for_pid_file= 0; + } + + if ($exe_libtool and $opt_valgrind) + { + # Add "libtool --mode-execute" + # if running in valgrind(to avoid valgrinding bash) + unshift(@$args, "--mode=execute", $exe); + $exe= $exe_libtool; + } + + + if ( defined $exe ) + { + $pid= mtr_spawn($exe, $args, "", + $mysqld->{'path_myerr'}, + $mysqld->{'path_myerr'}, + "", + { append_log_file => 1 }); + } + + + if ( $wait_for_pid_file && !sleep_until_file_created($mysqld->{'path_pid'}, + $mysqld->{'start_timeout'}, + $pid)) + { + + mtr_error("Failed to start mysqld $mysqld->{'type'}"); + } + + + # Remember pid of the started process + $mysqld->{'pid'}= $pid; + + # Remember options used when starting + $mysqld->{'start_opts'}= $extra_opt; + $mysqld->{'start_slave_master_info'}= $slave_master_info; + + mtr_verbose("mysqld pid: $pid"); + return $pid; +} + + +sub stop_all_servers () { + + print "Stopping All Servers\n"; + + if ( ! $opt_skip_im ) + { + print "Shutting-down Instance Manager\n"; + unless (mtr_im_stop($instance_manager, "stop_all_servers")) { - return sleep_until_file_created($master->[$idx]->{'path_mypid'}, - $master->[$idx]->{'start_timeout'}, $pid); + mtr_error("Failed to stop Instance Manager.") } } - if ( $type eq 'slave' ) + my %admin_pids; # hash of admin processes that requests shutdown + my @kill_pids; # list of processes to shutdown/kill + my $pid; + + # Start shutdown of all started masters + foreach my $mysqld (@{$master}, @{$slave}) { - if ( $pid= mtr_spawn($exe, $args, "", - $slave->[$idx]->{'path_myerr'}, - $slave->[$idx]->{'path_myerr'}, - "", - { append_log_file => 1 }) ) + if ( $mysqld->{'pid'} ) { - return sleep_until_file_created($slave->[$idx]->{'path_mypid'}, - $master->[$idx]->{'start_timeout'}, $pid); + $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70); + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $mysqld->{'pid'}, + pidfile => $mysqld->{'path_pid'}, + sockfile => $mysqld->{'path_sock'}, + port => $mysqld->{'port'}, + }); + + $mysqld->{'pid'}= 0; # Assume we are done with it } } - return 0; -} - -sub stop_masters_slaves () { - - print "Ending Tests\n"; - print "Shutting-down MySQL daemon\n\n"; - stop_masters(); - print "Master(s) shutdown finished\n"; - stop_slaves(); - print "Slave(s) shutdown finished\n"; -} - -sub stop_masters () { - - my @args; - - for ( my $idx; $idx < 2; $idx++ ) + # Start shutdown of clusters + foreach my $cluster (@{$clusters}) { - # FIXME if we hit ^C before fully started, this test will prevent - # the mysqld process from being killed - if ( $master->[$idx]->{'pid'} ) + if ( $cluster->{'pid'} ) { - push(@args,{ - pid => $master->[$idx]->{'pid'}, - pidfile => $master->[$idx]->{'path_mypid'}, - sockfile => $master->[$idx]->{'path_mysock'}, - port => $master->[$idx]->{'path_myport'}, - }); - $master->[$idx]->{'pid'}= 0; # Assume we are done with it + $pid= mtr_ndbmgm_start($cluster, "shutdown"); + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + if ( $ndbd->{'pid'} ) + { + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; + } + } } } - if ( ! $master->[0]->{'ndbcluster'} ) - { - ndbcluster_stop(); - $master->[0]->{'ndbcluster'}= 1; - } + # Wait blocking until all shutdown processes has completed + mtr_wait_blocking(\%admin_pids); - mtr_stop_mysqld_servers(\@args); + # Make sure that process has shutdown else try to kill them + mtr_check_stop_servers(\@kill_pids); + + foreach my $mysqld (@{$master}, @{$slave}) + { + rm_ndbcluster_tables($mysqld->{'path_myddir'}); + } } -sub stop_slaves () { - my $force= shift; - my @args; +sub run_testcase_need_master_restart($) +{ + my ($tinfo)= @_; - for ( my $idx; $idx < 3; $idx++ ) + # We try to find out if we are to restart the master(s) + my $do_restart= 0; # Assumes we don't have to + + if ( $tinfo->{'master_sh'} ) { - if ( $slave->[$idx]->{'pid'} ) + $do_restart= 1; # Always restart if script to run + mtr_verbose("Restart because: Always restart if script to run"); + } + elsif ( ! $opt_skip_ndbcluster and + $tinfo->{'ndb_test'} == 0 and + $clusters->[0]->{'pid'} != 0 ) + { + $do_restart= 1; # Restart without cluster + mtr_verbose("Restart because: Test does not need cluster"); + } + elsif ( ! $opt_skip_ndbcluster and + $tinfo->{'ndb_test'} == 1 and + $clusters->[0]->{'pid'} == 0 ) + { + $do_restart= 1; # Restart with cluster + mtr_verbose("Restart because: Test need cluster"); + } + elsif ( $master->[0]->{'running_master_is_special'} and + $master->[0]->{'running_master_is_special'}->{'timezone'} eq + $tinfo->{'timezone'} and + mtr_same_opts($master->[0]->{'running_master_is_special'}->{'master_opt'}, + $tinfo->{'master_opt'}) ) + { + # If running master was started with special settings, but + # the current test requires the same ones, we *don't* restart. + $do_restart= 0; + mtr_verbose("Skip restart: options are equal " . + join(" ", @{$tinfo->{'master_opt'}})); + } + elsif ( $tinfo->{'master_restart'} ) + { + $do_restart= 1; + mtr_verbose("Restart because: master_restart"); + } + elsif ( $master->[0]->{'running_master_is_special'} ) + { + $do_restart= 1; + mtr_verbose("Restart because: running_master_is_special"); + } + # Check that running master was started with same options + # as the current test requires + elsif (! mtr_same_opts($master->[0]->{'start_opts'}, + $tinfo->{'master_opt'}) ) + { + $do_restart= 1; + mtr_verbose("Restart because: running with different options '" . + join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . + join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); + } + + return $do_restart; +} + +sub run_testcase_need_slave_restart($) +{ + my ($tinfo)= @_; + + # We try to find out if we are to restart the slaves + my $do_slave_restart= 0; # Assumes we don't have to + + # FIXME only restart slave when necessary + $do_slave_restart= 1; + +# if ( ! $slave->[0]->{'pid'} ) +# { +# # mtr_verbose("Slave not started, no need to check slave restart"); +# } +# elsif ( $do_restart ) +# { +# $do_slave_restart= 1; # Always restart if master restart +# mtr_verbose("Restart slave because: Master restart"); +# } +# elsif ( $tinfo->{'slave_sh'} ) +# { +# $do_slave_restart= 1; # Always restart if script to run +# mtr_verbose("Restart slave because: Always restart if script to run"); +# } +# elsif ( ! $opt_skip_ndbcluster_slave and +# $tinfo->{'ndb_test'} == 0 and +# $clusters->[1]->{'pid'} != 0 ) +# { +# $do_slave_restart= 1; # Restart without slave cluster +# mtr_verbose("Restart slave because: Test does not need slave cluster"); +# } +# elsif ( ! $opt_with_ndbcluster_slave and +# $tinfo->{'ndb_test'} == 1 and +# $clusters->[1]->{'pid'} == 0 ) +# { +# $do_slave_restart= 1; # Restart with slave cluster +# mtr_verbose("Restart slave because: Test need slave cluster"); +# } +# elsif ( $tinfo->{'slave_restart'} ) +# { +# $do_slave_restart= 1; +# mtr_verbose("Restart slave because: slave_restart"); +# } +# elsif ( $slave->[0]->{'running_slave_is_special'} ) +# { +# $do_slave_restart= 1; +# mtr_verbose("Restart slave because: running_slave_is_special"); +# } +# # Check that running slave was started with same options +# # as the current test requires +# elsif (! mtr_same_opts($slave->[0]->{'start_opts'}, +# $tinfo->{'slave_opt'}) ) +# { +# $do_slave_restart= 1; +# mtr_verbose("Restart slave because: running with different options '" . +# join(" ", @{$tinfo->{'slave_opt'}}) . "' != '" . +# join(" ", @{$slave->[0]->{'start_opts'}}) . "'" ); +# } + + return $do_slave_restart; + +} + +# ---------------------------------------------------------------------- +# If not using a running servers we may need to stop and restart. +# We restart in the case we have initiation scripts, server options +# etc to run. But we also restart again after the test first restart +# and test is run, to get back to normal server settings. +# +# To make the code a bit more clean, we actually only stop servers +# here, and mark this to be done. Then a generic "start" part will +# start up the needed servers again. +# ---------------------------------------------------------------------- + +sub run_testcase_stop_servers($$$) { + my ($tinfo, $do_restart, $do_slave_restart)= @_; + + if ( $glob_use_running_server || $glob_use_embedded_server ) + { + return; + } + + my $pid; + my %admin_pids; # hash of admin processes that requests shutdown + my @kill_pids; # list of processes to shutdown/kill + + # Remember if we restarted for this test case + $tinfo->{'restarted'}= $do_restart; + + if ( $do_restart ) + { + delete $master->[0]->{'running_master_is_special'}; # Forget history + + # Start shutdown of all started masters + foreach my $mysqld (@{$master}) { - push(@args,{ - pid => $slave->[$idx]->{'pid'}, - pidfile => $slave->[$idx]->{'path_mypid'}, - sockfile => $slave->[$idx]->{'path_mysock'}, - port => $slave->[$idx]->{'path_myport'}, - }); - $slave->[$idx]->{'pid'}= 0; # Assume we are done with it + if ( $mysqld->{'pid'} ) + { + $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70); + + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $mysqld->{'pid'}, + pidfile => $mysqld->{'path_pid'}, + sockfile => $mysqld->{'path_sock'}, + port => $mysqld->{'port'}, + }); + + $mysqld->{'pid'}= 0; # Assume we are done with it + } + } + + # Start shutdown of master cluster + my $cluster= $clusters->[0]; + if ( $cluster->{'pid'} ) + { + $pid= mtr_ndbmgm_start($cluster, "shutdown"); + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}}) + { + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; # Assume we are done with it + } } } - mtr_stop_mysqld_servers(\@args); + if ( $do_restart || $do_slave_restart ) + { + + delete $slave->[0]->{'running_slave_is_special'}; # Forget history + + # Start shutdown of all started slaves + foreach my $mysqld (@{$slave}) + { + if ( $mysqld->{'pid'} ) + { + $pid= mtr_mysqladmin_start($mysqld, "shutdown", 70); + + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $mysqld->{'pid'}, + pidfile => $mysqld->{'path_pid'}, + sockfile => $mysqld->{'path_sock'}, + port => $mysqld->{'port'}, + }); + + + $mysqld->{'pid'}= 0; # Assume we are done with it + } + } + + # Start shutdown of slave cluster + my $cluster= $clusters->[1]; + if ( $cluster->{'pid'} ) + { + $pid= mtr_ndbmgm_start($cluster, "shutdown"); + + $admin_pids{$pid}= 1; + + push(@kill_pids,{ + pid => $cluster->{'pid'}, + pidfile => $cluster->{'path_pid'} + }); + + $cluster->{'pid'}= 0; # Assume we are done with it + + foreach my $ndbd (@{$cluster->{'ndbds'}} ) + { + push(@kill_pids,{ + pid => $ndbd->{'pid'}, + pidfile => $ndbd->{'path_pid'}, + }); + $ndbd->{'pid'}= 0; # Assume we are done with it + } + } + } + + # ---------------------------------------------------------------------- + # Shutdown has now been started and lists for the shutdown processes + # and the processes to be killed has been created + # ---------------------------------------------------------------------- + + # Wait blocking until all shutdown processes has completed + mtr_wait_blocking(\%admin_pids); + + + # Make sure that process has shutdown else try to kill them + mtr_check_stop_servers(\@kill_pids); + + foreach my $mysqld (@{$master}, @{$slave}) + { + if ( ! $mysqld->{'pid'} ) + { + # Remove ndbcluster tables if server is stopped + rm_ndbcluster_tables($mysqld->{'path_myddir'}); + } + } } +sub run_testcase_start_servers($) { + my $tinfo= shift; + + my $tname= $tinfo->{'name'}; + + if ( $glob_use_running_server or $glob_use_embedded_server ) + { + return; + } + + # ------------------------------------------------------- + # Init variables that can change between server starts + # ------------------------------------------------------- + $ENV{'TZ'}= $tinfo->{'timezone'}; + + if ( $tinfo->{'component_id'} eq 'mysqld' ) + { + if ( ! $opt_skip_ndbcluster and + !$clusters->[0]->{'pid'} and + $tinfo->{'ndb_test'} ) + { + # Test need cluster, cluster is not started, start it + ndbcluster_start($clusters->[0], ""); + } + + if ( !$master->[0]->{'pid'} ) + { + # Master mysqld is not started + do_before_start_master($tname,$tinfo->{'master_sh'}); + + mysqld_start($master->[0],$tinfo->{'master_opt'},[]); + + } + + if ( $clusters->[0]->{'pid'} and ! $master->[1]->{'pid'} ) + { + # Test needs cluster, start an extra mysqld connected to cluster + + # First wait for first mysql server to have created ndb system tables ok + # FIXME This is a workaround so that only one mysqld creates the tables + if ( ! sleep_until_file_created( + "$master->[0]->{'path_myddir'}/cluster/apply_status.ndb", + $master->[0]->{'start_timeout'}, + $master->[0]->{'pid'})) + { + mtr_report("Failed to create 'cluster/apply_status' table"); + report_failure_and_restart($tinfo); + return; + } + mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + + mysqld_start($master->[1],$tinfo->{'master_opt'},[]); + } + + if ( $tinfo->{'master_restart'} ) + { + # Save this test case information, so next can examine it + $master->[0]->{'running_master_is_special'}= $tinfo; + } + } + elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' ) + { + # We have to create defaults file every time, in order to ensure that it + # will be the same for each test. The problem is that test can change the + # file (by SET/UNSET commands), so w/o recreating the file, execution of + # one test can affect the other. + + im_create_defaults_file($instance_manager); + + unless ( mtr_im_start($instance_manager, $tinfo->{im_opts}) ) + { + report_failure_and_restart($tinfo); + mtr_report("Failed to start Instance Manager. " . + "The test '$tname' is marked as failed."); + return; + } + } + + # ---------------------------------------------------------------------- + # Start slaves - if needed + # ---------------------------------------------------------------------- + if ( $tinfo->{'slave_num'} ) + { + mtr_tofile($slave->[0]->{'path_myerr'},"CURRENT_TEST: $tname\n"); + + restore_slave_databases($tinfo->{'slave_num'}); + + do_before_start_slave($tname,$tinfo->{'slave_sh'}); + + if ( ! $opt_skip_ndbcluster_slave and + !$clusters->[1]->{'pid'} and + $tinfo->{'ndb_test'} ) + { + # Test need slave cluster, cluster is not started, start it + ndbcluster_start($clusters->[1], ""); + } + + for ( my $idx= 0; $idx < $tinfo->{'slave_num'}; $idx++ ) + { + if ( ! $slave->[$idx]->{'pid'} ) + { + mysqld_start($slave->[$idx],$tinfo->{'slave_opt'}, + $tinfo->{'slave_mi'}); + + } + } + + if ( $tinfo->{'slave_restart'} ) + { + # Save this test case information, so next can examine it + $slave->[0]->{'running_slave_is_special'}= $tinfo; + } + + } + + # Wait for clusters to start + foreach my $cluster (@{$clusters}) + { + + next if !$cluster->{'pid'}; + + if (ndbcluster_wait_started($cluster, "")) + { + # failed to start + mtr_report("Start of $cluster->{'name'} cluster failed, "); + } + } + + # Wait for mysqld's to start + foreach my $mysqld (@{$master},@{$slave}) + { + + next if !$mysqld->{'pid'}; + + if (mysqld_wait_started($mysqld)) + { + mtr_warning("Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}"); + } + } +} + +# +# Run include/check-testcase.test +# Before a testcase, run in record mode, save result file to var +# After testcase, run and compare with the recorded file, they should be equal! +# +sub run_check_testcase ($$) { + + my $mode= shift; + my $mysqld= shift; + + my $name= "check-" . $mysqld->{'type'} . $mysqld->{'idx'}; + + my $args; + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--silent"); + mtr_add_arg($args, "-v"); + mtr_add_arg($args, "--skip-safemalloc"); + mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); + + mtr_add_arg($args, "--socket=%s", $mysqld->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $mysqld->{'port'}); + mtr_add_arg($args, "--database=test"); + mtr_add_arg($args, "--user=%s", $opt_user); + mtr_add_arg($args, "--password="); + + mtr_add_arg($args, "-R"); + mtr_add_arg($args, "$opt_vardir/tmp/$name.result"); + + if ( $mode eq "before" ) + { + mtr_add_arg($args, "--record"); + } + + my $res = mtr_run_test($exe_mysqltest,$args, + "include/check-testcase.test", "", "", ""); + + if ( $res == 1 and $mode = "after") + { + mtr_run("diff",["-u", + "$opt_vardir/tmp/$name.result", + "$opt_vardir/tmp/$name.reject"], + "", "", "", ""); + } + elsif ( $res ) + { + mtr_error("Could not execute 'check-testcase' $mode testcase"); + } +} + + sub run_mysqltest ($) { - my $tinfo= shift; - - my $cmdline_mysqldump= "$exe_mysqldump --no-defaults -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqldump .= - " --debug=d:t:A,$opt_vardir/log/mysqldump.trace"; - } - my $cmdline_mysqlimport= "$exe_mysqlimport -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqlimport .= - " --debug=d:t:A,$opt_vardir/log/mysqlimport.trace"; - } - - my $cmdline_mysqlshow= "$exe_mysqlshow -uroot " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'} --password="; - if ( $opt_debug ) - { - $cmdline_mysqlshow .= - " --debug=d:t:A,$opt_vardir/log/mysqlshow.trace"; - } - - my $cmdline_mysqlbinlog= - "$exe_mysqlbinlog --no-defaults --local-load=$opt_tmpdir"; - - if ( $opt_debug ) - { - $cmdline_mysqlbinlog .= - " --debug=d:t:A,$opt_vardir/log/mysqlbinlog.trace"; - } - - my $cmdline_mysql= - "$exe_mysql --host=localhost --user=root --password= " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'}"; - - my $cmdline_mysql_client_test= - "$exe_mysql_client_test --no-defaults --testcase --user=root --silent " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'}"; - - if ( $glob_use_embedded_server ) - { - $cmdline_mysql_client_test.= - " -A --language=$path_language" . - " -A --datadir=$slave->[0]->{'path_myddir'}" . - " -A --character-sets-dir=$path_charsetsdir"; - } - - my $cmdline_mysql_fix_system_tables= - "$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " . - "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . - "--port=$master->[0]->{'path_myport'} " . - "--socket=$master->[0]->{'path_mysock'}"; - - - - # FIXME really needing a PATH??? - # $ENV{'PATH'}= "/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$ENV{'PATH'}"; - - $ENV{'MYSQL'}= $cmdline_mysql; - $ENV{'MYSQL_DUMP'}= $cmdline_mysqldump; - $ENV{'MYSQL_IMPORT'}= $cmdline_mysqlimport; - $ENV{'MYSQL_SHOW'}= $cmdline_mysqlshow; - $ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog; - $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; - $ENV{'MYSQL_CLIENT_TEST'}= $cmdline_mysql_client_test; - $ENV{'CHARSETSDIR'}= $path_charsetsdir; - $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; - - $ENV{'NDB_STATUS_OK'}= $flag_ndb_status_ok; - $ENV{'NDB_MGM'}= $exe_ndb_mgm; - $ENV{'NDB_BACKUP_DIR'}= $path_ndb_backup_dir; - $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; - $ENV{'NDB_TOOLS_OUTPUT'}= $file_ndb_testrun_log; - $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; - + my ($tinfo)= @_; my $exe= $exe_mysqltest; my $args; mtr_init_args(\$args); mtr_add_arg($args, "--no-defaults"); - mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_mysock'}); - mtr_add_arg($args, "--database=test"); - mtr_add_arg($args, "--user=%s", $opt_user); - mtr_add_arg($args, "--password="); mtr_add_arg($args, "--silent"); mtr_add_arg($args, "-v"); mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); - mtr_add_arg($args, "--port=%d", $master->[0]->{'path_myport'}); + + if ($tinfo->{'component_id'} eq 'im') + { + mtr_add_arg($args, "--socket=%s", $instance_manager->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $instance_manager->{'port'}); + mtr_add_arg($args, "--user=%s", $instance_manager->{'admin_login'}); + mtr_add_arg($args, "--password=%s", $instance_manager->{'admin_password'}); + } + else # component_id == mysqld + { + mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $master->[0]->{'port'}); + mtr_add_arg($args, "--database=test"); + mtr_add_arg($args, "--user=%s", $opt_user); + mtr_add_arg($args, "--password="); + } if ( $opt_ps_protocol ) { mtr_add_arg($args, "--ps-protocol"); } + if ( $opt_sp_protocol ) + { + mtr_add_arg($args, "--sp-protocol"); + } + + if ( $opt_view_protocol ) + { + mtr_add_arg($args, "--view-protocol"); + } + + if ( $opt_cursor_protocol ) + { + mtr_add_arg($args, "--cursor-protocol"); + } + if ( $opt_strace_client ) { $exe= "strace"; # FIXME there are ktrace, .... @@ -2392,6 +3869,11 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--big-test"); } + if ( $opt_valgrind ) + { + mtr_add_arg($args, "--valgrind"); + } + if ( $opt_compress ) { mtr_add_arg($args, "--compress"); @@ -2404,17 +3886,30 @@ sub run_mysqltest ($) { if ( $opt_debug ) { - mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", $opt_vardir); + mtr_add_arg($args, "--debug=d:t:A,%s/log/mysqltest.trace", + $path_vardir_trace); } - if ( $opt_with_openssl ) + if ( $opt_ssl_supported ) { mtr_add_arg($args, "--ssl-ca=%s/std_data/cacert.pem", - $glob_mysql_test_dir); + $glob_mysql_test_dir); mtr_add_arg($args, "--ssl-cert=%s/std_data/client-cert.pem", - $glob_mysql_test_dir); + $glob_mysql_test_dir); mtr_add_arg($args, "--ssl-key=%s/std_data/client-key.pem", - $glob_mysql_test_dir); + $glob_mysql_test_dir); + } + + if ( $opt_ssl ) + { + # Turn on SSL for _all_ test cases if option --ssl was used + mtr_add_arg($args, "--ssl", + $glob_mysql_test_dir); + } + elsif ( $opt_ssl_supported ) + { + mtr_add_arg($args, "--skip-ssl", + $glob_mysql_test_dir); } # ---------------------------------------------------------------------- @@ -2435,7 +3930,7 @@ sub run_mysqltest ($) { # Add arguments that should not go into the MYSQL_TEST env var # ---------------------------------------------------------------------- - if ( defined $opt_valgrind_mysqltest ) + if ( $opt_valgrind_mysqltest ) { # Prefix the Valgrind options to the argument list. # We do this here, since we do not want to Valgrind the nested invocations @@ -2446,7 +3941,10 @@ sub run_mysqltest ($) { mtr_add_arg($args, "%s", $_) for @args_saved; } - mtr_add_arg($args, "-R"); + mtr_add_arg($args, "--test-file"); + mtr_add_arg($args, $tinfo->{'path'}); + + mtr_add_arg($args, "--result-file"); mtr_add_arg($args, $tinfo->{'result_file'}); if ( $opt_record ) @@ -2454,36 +3952,248 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--record"); } - return mtr_run_test($exe,$args,$tinfo->{'path'},"",$path_timefile,""); + if ( $opt_client_gdb ) + { + gdb_arguments(\$args, \$exe, "client"); + } + elsif ( $opt_client_ddd ) + { + ddd_arguments(\$args, \$exe, "client"); + } + elsif ( $opt_client_debugger ) + { + debugger_arguments(\$args, \$exe, "client"); + } + + if ($exe_libtool and $opt_valgrind) + { + # Add "libtool --mode-execute" before the test to execute + # if running in valgrind(to avoid valgrinding bash) + unshift(@$args, "--mode=execute", $exe); + $exe= $exe_libtool; + } + + if ( $opt_check_testcases ) + { + foreach my $mysqld (@{$master}, @{$slave}) + { + if ($mysqld->{'pid'}) + { + run_check_testcase("before", $mysqld); + } + } + } + + my $res = mtr_run_test($exe,$args,"","",$path_timefile,""); + + if ( $opt_check_testcases ) + { + foreach my $mysqld (@{$master}, @{$slave}) + { + if ($mysqld->{'pid'}) + { + run_check_testcase("after", $mysqld); + } + } + } + + return $res; + } +# +# Modify the exe and args so that program is run in gdb in xterm +# +sub gdb_arguments { + my $args= shift; + my $exe= shift; + my $type= shift; + + # Write $args to gdb init file + my $str= join(" ", @$$args); + my $gdb_init_file= "$opt_tmpdir/gdbinit.$type"; + + # Remove the old gdbinit file + unlink($gdb_init_file); + + if ( $type eq "client" ) + { + # write init file for client + mtr_tofile($gdb_init_file, + "set args $str\n" . + "break main\n"); + } + else + { + # write init file for mysqld + mtr_tofile($gdb_init_file, + "set args $str\n" . + "break mysql_parse\n" . + "commands 1\n" . + "disable 1\n" . + "end\n" . + "run"); + } + + if ( $opt_manual_gdb ) + { + print "\nTo start gdb for $type, type in another window:\n"; + print "cd $glob_mysql_test_dir;\n"; + print "gdb -x $gdb_init_file $$exe\n"; + + # Indicate the exe should not be started + $$exe= undef; + return; + } + + $$args= []; + mtr_add_arg($$args, "-title"); + mtr_add_arg($$args, "$type"); + mtr_add_arg($$args, "-e"); + + if ( $exe_libtool ) + { + mtr_add_arg($$args, $exe_libtool); + mtr_add_arg($$args, "--mode=execute"); + } + + mtr_add_arg($$args, "gdb"); + mtr_add_arg($$args, "-x"); + mtr_add_arg($$args, "$gdb_init_file"); + mtr_add_arg($$args, "$$exe"); + + $$exe= "xterm"; +} + + +# +# Modify the exe and args so that program is run in ddd +# +sub ddd_arguments { + my $args= shift; + my $exe= shift; + my $type= shift; + + # Write $args to ddd init file + my $str= join(" ", @$$args); + my $gdb_init_file= "$opt_tmpdir/gdbinit.$type"; + + # Remove the old gdbinit file + unlink($gdb_init_file); + + if ( $type eq "client" ) + { + # write init file for client + mtr_tofile($gdb_init_file, + "set args $str\n" . + "break main\n"); + } + else + { + # write init file for mysqld + mtr_tofile($gdb_init_file, + "file $$exe\n" . + "set args $str\n" . + "break mysql_parse\n" . + "commands 1\n" . + "disable 1\n" . + "end"); + } + + if ( $opt_manual_ddd ) + { + print "\nTo start ddd for $type, type in another window:\n"; + print "cd $glob_mysql_test_dir;\n"; + print "ddd -x $gdb_init_file $$exe\n"; + + # Indicate the exe should not be started + $$exe= undef; + return; + } + + my $save_exe= $$exe; + $$args= []; + if ( $exe_libtool ) + { + $$exe= $exe_libtool; + mtr_add_arg($$args, "--mode=execute"); + mtr_add_arg($$args, "ddd"); + } + else + { + $$exe= "ddd"; + } + mtr_add_arg($$args, "--command=$gdb_init_file"); + mtr_add_arg($$args, "$save_exe"); +} + + +# +# Modify the exe and args so that program is run in the selected debugger +# +sub debugger_arguments { + my $args= shift; + my $exe= shift; + my $debugger= $opt_debugger || $opt_client_debugger; + + # FIXME Need to change the below "eq"'s to + # "case unsensitive string contains" + if ( $debugger eq "vcexpress" or $debugger eq "vc") + { + # vc[express] /debugexe exe arg1 .. argn + + # Add /debugexe and name of the exe before args + unshift(@$$args, "/debugexe"); + unshift(@$$args, "$$exe"); + + } + elsif ( $debugger eq "windbg" ) + { + # windbg exe arg1 .. argn + + # Add name of the exe before args + unshift(@$$args, "$$exe"); + + } + else + { + mtr_error("Unknown argument \"$debugger\" passed to --debugger"); + } + + # Set exe to debuggername + $$exe= $debugger; +} + + +# +# Modify the exe and args so that program is run in valgrind +# sub valgrind_arguments { my $args= shift; my $exe= shift; - mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option - mtr_add_arg($args, "--alignment=8"); - mtr_add_arg($args, "--leak-check=yes"); - mtr_add_arg($args, "--num-callers=16"); - mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) - if -f "$glob_mysql_test_dir/valgrind.supp"; - - if ( defined $opt_valgrind_all ) + if ( $opt_callgrind) { - mtr_add_arg($args, "-v"); - mtr_add_arg($args, "--show-reachable=yes"); + mtr_add_arg($args, "--tool=callgrind"); + mtr_add_arg($args, "--base=$opt_vardir/log"); + } + else + { + mtr_add_arg($args, "--tool=memcheck"); # From >= 2.1.2 needs this option + mtr_add_arg($args, "--alignment=8"); + mtr_add_arg($args, "--leak-check=yes"); + mtr_add_arg($args, "--num-callers=16"); + mtr_add_arg($args, "--suppressions=%s/valgrind.supp", $glob_mysql_test_dir) + if -f "$glob_mysql_test_dir/valgrind.supp"; } - if ( $opt_valgrind_options ) - { - # FIXME split earlier and put into @glob_valgrind_* - mtr_add_arg($args, '%s', $_) for (split(' ', $opt_valgrind_options)); - } + # Add valgrind options, can be overriden by user + mtr_add_arg($args, '%s', $_) for (split(' ', $opt_valgrind_options)); mtr_add_arg($args, $$exe); - $$exe= $opt_valgrind || "valgrind"; + $$exe= $opt_valgrind_path || "valgrind"; } @@ -2503,38 +4213,60 @@ sub usage ($) { print STDERR < Date: Wed, 4 Oct 2006 13:09:37 +0200 Subject: [PATCH 040/235] Update tests and result files after running with new mysqltest that better detects problems with test files mysql-test/r/csv.result: Update after add of missing semicolon mysql-test/r/drop.result: Update result file, no space before commands that has been "sent" mysql-test/r/flush.result: Update result file, no space before commands that has been "sent" mysql-test/r/flush_block_commit.result: Update result file, no space before commands that has been "sent" mysql-test/r/flush_read_lock_kill.result: Update result file, no space before commands that has been "sent" mysql-test/r/grant2.result: Update result file, no space before commands that has been "sent" mysql-test/r/handler.result: Update result file, no space before commands that has been "sent" mysql-test/r/innodb_notembedded.result: Update result file, no space before commands that has been "sent" mysql-test/r/kill.result: Update result file, no space before commands that has been "sent" mysql-test/r/lock_multi.result: Update result file, no space before commands that has been "sent" mysql-test/r/multi_update.result: Update result file, no space before commands that has been "sent" mysql-test/r/mysqltest.result: Update result mysql-test/r/query_cache.result: Update after add of missing semicolon mysql-test/r/query_cache_notembedded.result: Update result file, no space before commands that has been "sent" mysql-test/r/sp-threads.result: Update result file, no space before commands that has been "sent" mysql-test/r/sp_notembedded.result: Update after add of missing semicolon mysql-test/r/type_blob.result: Remove extra drop table mysql-test/t/csv.test: Add missing semicolon mysql-test/t/query_cache.test: Add missing semicolon mysql-test/t/sp-error.test: Remove "tab" from end of error declaration mysql-test/t/sp.test: Wrong delimiter, used ; instead of | mysql-test/t/sp_notembedded.test: Wrong delimiter, used ; instead of | mysql-test/t/view_grant.test: An incomplete error name specification was used. --- mysql-test/r/csv.result | 3 +-- mysql-test/r/drop.result | 4 ++-- mysql-test/r/flush.result | 4 ++-- mysql-test/r/flush_block_commit.result | 2 +- mysql-test/r/flush_read_lock_kill.result | 2 +- mysql-test/r/grant2.result | 8 ++++---- mysql-test/r/handler.result | 4 ++-- mysql-test/r/innodb_notembedded.result | 2 +- mysql-test/r/kill.result | 4 ++-- mysql-test/r/lock_multi.result | 12 ++++++------ mysql-test/r/multi_update.result | 4 ++-- mysql-test/r/mysqltest.result | 2 +- mysql-test/r/query_cache.result | 3 +-- mysql-test/r/query_cache_notembedded.result | 2 +- mysql-test/r/sp-threads.result | 4 ++-- mysql-test/r/sp_notembedded.result | 3 +-- mysql-test/r/type_blob.result | 1 - mysql-test/t/csv.test | 2 +- mysql-test/t/query_cache.test | 2 +- mysql-test/t/sp-error.test | 2 +- mysql-test/t/sp.test | 10 +++++----- mysql-test/t/sp_notembedded.test | 12 ++++++------ mysql-test/t/view_grant.test | 2 +- 23 files changed, 45 insertions(+), 49 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index f3e91a663b8..8ec79e9d7a9 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -4913,8 +4913,7 @@ bonfire Colombo nondecreasing DROP TABLE t1; -ALTER TABLE t2 RENAME t1 -#; +ALTER TABLE t2 RENAME t1; DROP TABLE t1; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, diff --git a/mysql-test/r/drop.result b/mysql-test/r/drop.result index d122dabc4ec..ff11905aa34 100644 --- a/mysql-test/r/drop.result +++ b/mysql-test/r/drop.result @@ -77,9 +77,9 @@ drop table if exists t1; create table t1 (i int); lock tables t1 read; create database mysqltest; - drop table t1; +drop table t1; show open tables; - drop database mysqltest; +drop database mysqltest; select 1; 1 1 diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index 23c7619c31c..7eb7fd16edb 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -51,7 +51,7 @@ drop table t1, t2, t3; create table t1 (c1 int); create table t2 (c1 int); lock table t1 write; - flush tables with read lock; - insert into t2 values(1); +flush tables with read lock; +insert into t2 values(1); unlock tables; drop table t1, t2; diff --git a/mysql-test/r/flush_block_commit.result b/mysql-test/r/flush_block_commit.result index 7dbbd4678df..9e9085d2fc8 100644 --- a/mysql-test/r/flush_block_commit.result +++ b/mysql-test/r/flush_block_commit.result @@ -45,7 +45,7 @@ flush tables with read lock; show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 98 - commit; +commit; show master status; File Position Binlog_Do_DB Binlog_Ignore_DB master-bin.000001 98 diff --git a/mysql-test/r/flush_read_lock_kill.result b/mysql-test/r/flush_read_lock_kill.result index dfdcf51457a..6703b6bd533 100644 --- a/mysql-test/r/flush_read_lock_kill.result +++ b/mysql-test/r/flush_read_lock_kill.result @@ -1,7 +1,7 @@ drop table if exists t1; create table t1 (kill_id int); insert into t1 values(connection_id()); - flush tables with read lock; +flush tables with read lock; select ((@id := kill_id) - kill_id) from t1; ((@id := kill_id) - kill_id) 0 diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 2700426257b..ff9b7bc6f1f 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -336,12 +336,12 @@ drop database mysqltest_1; set password = password("changed"); ERROR 42000: Access denied for user ''@'localhost' to database 'mysql' lock table mysql.user write; - flush privileges; - grant all on *.* to 'mysqltest_1'@'localhost'; +flush privileges; +grant all on *.* to 'mysqltest_1'@'localhost'; unlock tables; lock table mysql.user write; - set password for 'mysqltest_1'@'localhost' = password(''); - revoke all on *.* from 'mysqltest_1'@'localhost'; +set password for 'mysqltest_1'@'localhost' = password(''); +revoke all on *.* from 'mysqltest_1'@'localhost'; unlock tables; drop user 'mysqltest_1'@'localhost'; create database TESTDB; diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result index 104025e83eb..85cf47b5806 100644 --- a/mysql-test/r/handler.result +++ b/mysql-test/r/handler.result @@ -452,7 +452,7 @@ handler t1 read first; c1 1 send the below to another connection, do not wait for the result - optimize table t1; +optimize table t1; proceed with the normal connection handler t1 read next; c1 @@ -469,7 +469,7 @@ flush tables with read lock; drop table t1; ERROR HY000: Can't execute the query because you have a conflicting read lock send the below to another connection, do not wait for the result - drop table t1; +drop table t1; proceed with the normal connection select * from t1; c1 diff --git a/mysql-test/r/innodb_notembedded.result b/mysql-test/r/innodb_notembedded.result index 9aac20e515d..cc13a429dfc 100644 --- a/mysql-test/r/innodb_notembedded.result +++ b/mysql-test/r/innodb_notembedded.result @@ -10,7 +10,7 @@ start transaction; select f1(); f1() 100 - update t1 set col2=0 where col1=1; +update t1 set col2=0 where col1=1; select * from t1; col1 col2 1 100 diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index b78c677fb02..cf5486d1091 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -22,7 +22,7 @@ create table t2 (id int unsigned not null); insert into t2 select id from t1; create table t3 (kill_id int); insert into t3 values(connection_id()); - select id from t1 where id in (select distinct id from t2); +select id from t1 where id in (select distinct id from t2); select ((@id := kill_id) - kill_id) from t3; ((@id := kill_id) - kill_id) 0 @@ -32,7 +32,7 @@ drop table t1, t2, t3; select get_lock("a", 10); get_lock("a", 10) 1 - select get_lock("a", 10); +select get_lock("a", 10); get_lock("a", 10) NULL select 1; diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index c9d5eafd115..af49e1a27dc 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -45,7 +45,7 @@ unlock tables; drop table t1; CREATE DATABASE mysqltest_1; FLUSH TABLES WITH READ LOCK; - DROP DATABASE mysqltest_1; +DROP DATABASE mysqltest_1; DROP DATABASE mysqltest_1; ERROR HY000: Can't execute the query because you have a conflicting read lock UNLOCK TABLES; @@ -55,7 +55,7 @@ use mysql; LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE; FLUSH TABLES; use mysql; - SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; +SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; OPTIMIZE TABLES columns_priv, db, host, user; Table Op Msg_type Msg_text mysql.columns_priv optimize status OK @@ -69,14 +69,14 @@ use test; use test; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; - FLUSH TABLES WITH READ LOCK; +FLUSH TABLES WITH READ LOCK; CREATE TABLE t2 (c1 int); UNLOCK TABLES; UNLOCK TABLES; DROP TABLE t1, t2; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; - FLUSH TABLES WITH READ LOCK; +FLUSH TABLES WITH READ LOCK; CREATE TABLE t2 AS SELECT * FROM t1; ERROR HY000: Table 't2' was not locked with LOCK TABLES UNLOCK TABLES; @@ -84,7 +84,7 @@ UNLOCK TABLES; DROP TABLE t1; create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; lock tables t1 write; - alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // - alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // +alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // +alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // unlock tables; drop table t1; diff --git a/mysql-test/r/multi_update.result b/mysql-test/r/multi_update.result index b4a7aa5cb76..78872f27c47 100644 --- a/mysql-test/r/multi_update.result +++ b/mysql-test/r/multi_update.result @@ -509,8 +509,8 @@ create table t2 (a int); insert into t2 values (10), (20), (30); create view v1 as select a as b, a/10 as a from t2; lock table t1 write; - alter table t1 add column c int default 100 after a; - update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a; +alter table t1 add column c int default 100 after a; +update t1, v1 set t1.b=t1.a+t1.b+v1.b where t1.a=v1.a; unlock tables; select * from t1; a c b diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 7276397bdc7..628ba7f9c88 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -163,7 +163,7 @@ mysqltest: At line 1: Invalid argument to error: '1sssss' - the errno may only c mysqltest: At line 1: The sqlstate must be exactly 5 chars long mysqltest: At line 1: The sqlstate may only consist of digits[0-9] and _uppercase_ letters mysqltest: At line 1: The sqlstate must be exactly 5 chars long -mysqltest: At line 1: Not available in mysqltest for MySQL 4.1.22 +mysqltest: At line 1: Unknown SQL error name 'E9999' mysqltest: At line 1: Invalid argument to error: '999e9' - the errno may only consist of digits[0-9] mysqltest: At line 1: Invalid argument to error: '9b' - the errno may only consist of digits[0-9] mysqltest: At line 1: Too many errorcodes specified diff --git a/mysql-test/r/query_cache.result b/mysql-test/r/query_cache.result index a735b52a26f..ebf0148c7fd 100644 --- a/mysql-test/r/query_cache.result +++ b/mysql-test/r/query_cache.result @@ -932,8 +932,7 @@ abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzab zyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba flush query cache; drop table t1, t2; -set GLOBAL query_cache_size=1355776 -#; +set GLOBAL query_cache_size=1355776; flush status; CREATE TABLE t1 ( `date` datetime NOT NULL default '0000-00-00 00:00:00', diff --git a/mysql-test/r/query_cache_notembedded.result b/mysql-test/r/query_cache_notembedded.result index 4226738725a..8e5df012cfb 100644 --- a/mysql-test/r/query_cache_notembedded.result +++ b/mysql-test/r/query_cache_notembedded.result @@ -326,7 +326,7 @@ insert into t1 values(3); set i_var = sleep(3); return 0; end;| - select f1(); +select f1(); select sleep(4); sleep(4) 0 diff --git a/mysql-test/r/sp-threads.result b/mysql-test/r/sp-threads.result index c516d7a643f..953830ecc87 100644 --- a/mysql-test/r/sp-threads.result +++ b/mysql-test/r/sp-threads.result @@ -31,7 +31,7 @@ create procedure bug9486() update t1, t2 set val= 1 where id1=id2; call bug9486(); lock tables t2 write; - call bug9486(); +call bug9486(); show processlist; Id User Host db Command Time State Info # root localhost test Sleep # NULL @@ -77,7 +77,7 @@ select * from t1; end| use test; lock table t1 write; - call p2(); +call p2(); use test; drop procedure p1; create procedure p1() select * from t1; diff --git a/mysql-test/r/sp_notembedded.result b/mysql-test/r/sp_notembedded.result index bcde32572c2..60e427e17a5 100644 --- a/mysql-test/r/sp_notembedded.result +++ b/mysql-test/r/sp_notembedded.result @@ -85,8 +85,7 @@ flush status| flush query cache| delete from t1| drop procedure bug3583| -drop table t1; -#| +drop table t1| drop procedure if exists bug6807| create procedure bug6807() begin diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index 4eb5b129a83..73b67a2241e 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -26,7 +26,6 @@ t3 CREATE TABLE `t3` ( `a` mediumtext, `b` mediumblob ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -drop table t1,t2,t3; show create TABLE t4; Table Create Table t4 CREATE TABLE `t4` ( diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 8bd48b7da2c..65173cbf355 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1295,7 +1295,7 @@ SELECT fld3 FROM t2; # DROP TABLE t1; -ALTER TABLE t2 RENAME t1 +ALTER TABLE t2 RENAME t1; # # Drop and recreate diff --git a/mysql-test/t/query_cache.test b/mysql-test/t/query_cache.test index d416f34ce45..d86f1a464b1 100644 --- a/mysql-test/t/query_cache.test +++ b/mysql-test/t/query_cache.test @@ -695,7 +695,7 @@ select a from t1; flush query cache; drop table t1, t2; -set GLOBAL query_cache_size=1355776 +set GLOBAL query_cache_size=1355776; # diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index abb36f040d2..a229c7b7665 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -319,7 +319,7 @@ begin declare x int; end| ---error 1332 +--error 1332 create procedure p() begin declare c condition for 1064; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 4b0f463a9e3..1d20fd0ad02 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -2944,11 +2944,11 @@ begin show warnings; end| --disable_parsing -show binlog events; -show storage engines; -show master status; -show slave hosts; -show slave status; +show binlog events| +show storage engines| +show master status| +show slave hosts| +show slave status| --enable_parsing call bug4902()| diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test index b087f699f86..4e18e69d3d2 100644 --- a/mysql-test/t/sp_notembedded.test +++ b/mysql-test/t/sp_notembedded.test @@ -19,11 +19,11 @@ begin show grants for 'root'@'localhost'; end| --disable_parsing -show binlog events; -show storage engines; -show master status; -show slave hosts; -show slave status; +show binlog events| +show storage engines| +show master status| +show slave hosts| +show slave status| --enable_parsing call bug4902()| @@ -108,7 +108,7 @@ flush status| flush query cache| delete from t1| drop procedure bug3583| -drop table t1; +drop table t1| # # BUG#6807: Stored procedure crash if CREATE PROCEDURE ... KILL QUERY diff --git a/mysql-test/t/view_grant.test b/mysql-test/t/view_grant.test index c75e5422de7..8bc34cfe148 100644 --- a/mysql-test/t/view_grant.test +++ b/mysql-test/t/view_grant.test @@ -26,7 +26,7 @@ grant create view,select on test.* to mysqltest_1@localhost; connect (user1,localhost,mysqltest_1,,test); connection user1; --- error ER_SPECIFIC_ACCESS_DENIED +-- error ER_SPECIFIC_ACCESS_DENIED_ERROR create definer=root@localhost view v1 as select * from mysqltest.t1; create view v1 as select * from mysqltest.t1; # try to modify view without DROP privilege on it From 634d3ff2c658902fa3ed4eb0f988a79564cfe94e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 17:13:32 +0400 Subject: [PATCH 041/235] Fixes a number of problems with time/datetime <-> string conversion functions: - bug #11655 "Wrong time is returning from nested selects - maximum time exists - input and output TIME values were not validated properly in several conversion functions - bug #20927 "sec_to_time treats big unsigned as signed" - integer overflows were not checked in several functions. As a result, input values like 2^32 or 3600*2^32 were treated as 0 - BIGINT UNSIGNED values were treated as SIGNED in several functions - in cases where both input string truncation and out-of-range TIME value occur, only 'truncated incorrect time value' warning was produced include/my_time.h: Added defines for the TIME limits Added defines for the warning flags set by str_to_time() and check_time_range() Added check_time_range() declaration mysql-test/r/func_sapdb.result: Fixed testcases which relied on incorrect TIMEDIFF() behaviour mysql-test/r/func_time.result: Fixed testcase which relied on incorrect behaviour Added testcases for out-of-range values in SEC_TO_TIME(), TIME_TO_SEC(), ADDTIME(), SUBTIME() and EXTRACT() mysql-test/t/func_time.test: Added testcases for out-of-range values in SEC_TO_TIME(), TIME_TO_SEC(), ADDTIME(), SUBTIME() and EXTRACT() sql-common/my_time.c: Added check_time_range() to be used from str_to_time() and item_timefunc.cc Added new out-of-range flag to str_to_time() warnings Use '%u' instead of '%d' in my_*_to_str() because the arguments are unsigned sql/field.cc: Replaced out-of-range checks with checks for flags returned by str_to_time() sql/item_timefunc.cc: Added wrappers over make_datetime() and make_time() which perform out-of-range checks on input values Moved common code in Item_func_sec_to_time::val_str() and Item_func_sec_to_time::val_int() into a separate function sec_to_time() Replaced calls to make_datetime() with make_datetime_with_warn() in Item_func_add_time and Item_func_timediff Checks for 'unsigned int' overflows in Item_func_maketime Use make_time_with_warn() instead of make_time() in Item_func_maketime Fixed incorrect sizeof() in Item_func_str_to_date::get_time() sql/time.cc: Check for return value of str_to_time() along with warning flags --- include/my_time.h | 14 +- mysql-test/r/func_sapdb.result | 15 ++- mysql-test/r/func_time.result | 92 +++++++++++++- mysql-test/t/func_time.test | 45 ++++++- sql-common/my_time.c | 91 +++++++++---- sql/field.cc | 35 +++-- sql/item_timefunc.cc | 226 ++++++++++++++++++++++++++------- sql/time.cc | 6 +- 8 files changed, 429 insertions(+), 95 deletions(-) diff --git a/include/my_time.h b/include/my_time.h index 94701e159c4..11c653f70d0 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -44,12 +44,24 @@ typedef long my_time_t; #define TIME_FUZZY_DATE 1 #define TIME_DATETIME_ONLY 2 +#define MYSQL_TIME_WARN_TRUNCATED 1 +#define MYSQL_TIME_WARN_OUT_OF_RANGE 2 + +/* Limits for the TIME data type */ +#define TIME_MAX_HOUR 838 +#define TIME_MAX_MINUTE 59 +#define TIME_MAX_SECOND 59 +#define TIME_MAX_VALUE (TIME_MAX_HOUR*10000 + TIME_MAX_MINUTE*100 + \ + TIME_MAX_SECOND) + enum enum_mysql_timestamp_type str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, uint flags, int *was_cut); bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time, - int *was_cut); + int *warning); + +int check_time_range(struct st_mysql_time *time, int *warning); long calc_daynr(uint year,uint month,uint day); diff --git a/mysql-test/r/func_sapdb.result b/mysql-test/r/func_sapdb.result index b18885e218a..447cadb9898 100644 --- a/mysql-test/r/func_sapdb.result +++ b/mysql-test/r/func_sapdb.result @@ -97,7 +97,9 @@ subtime("02:01:01.999999", "01:01:01.999999") 01:00:00.000000 select timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002"); timediff("1997-01-01 23:59:59.000001","1995-12-31 23:59:59.000002") -8807:59:59.999999 +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '8807:59:59.999999' select timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002"); timediff("1997-12-31 23:59:59.000001","1997-12-30 01:01:01.000002") 46:58:57.999999 @@ -208,13 +210,16 @@ NULL NULL SELECT TIMEDIFF(t1,t4) As ttt, TIMEDIFF(t2, t3) As qqq from test; ttt qqq -744:00:00 NULL -26305:01:02 22:58:58 --26305:01:02 -22:58:58 +838:59:59 22:58:58 +-838:59:59 -22:58:58 NULL 26:02:02 00:00:00 -26:02:02 NULL NULL NULL NULL 00:00:00 -24:00:00 +Warnings: +Warning 1292 Truncated incorrect time value: '26305:01:02' +Warning 1292 Truncated incorrect time value: '-26305:01:02' drop table t1, test; select addtime("-01:01:01.01", "-23:59:59.1") as a; a @@ -224,7 +229,9 @@ a 10000 select microsecond(19971231235959.01) as a; a -10000 +0 +Warnings: +Warning 1292 Truncated incorrect time value: '19971231235959.01' select date_add("1997-12-31",INTERVAL "10.09" SECOND_MICROSECOND) as a; a 1997-12-31 00:00:10.090000 diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index fab0bf01f58..381c147660a 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -330,7 +330,9 @@ extract(DAY_MINUTE FROM "02 10:11:12") 21011 select extract(DAY_SECOND FROM "225 10:11:12"); extract(DAY_SECOND FROM "225 10:11:12") -225101112 +8385959 +Warnings: +Warning 1292 Truncated incorrect time value: '225 10:11:12' select extract(HOUR FROM "1999-01-02 10:11:12"); extract(HOUR FROM "1999-01-02 10:11:12") 10 @@ -688,3 +690,91 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +SELECT SEC_TO_TIME(3300000); +SEC_TO_TIME(3300000) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '3300000' +SELECT SEC_TO_TIME(3300000)+0; +SEC_TO_TIME(3300000)+0 +8385959.000000 +Warnings: +Warning 1292 Truncated incorrect time value: '3300000' +SELECT SEC_TO_TIME(3600 * 4294967296); +SEC_TO_TIME(3600 * 4294967296) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '15461882265600' +SELECT TIME_TO_SEC('916:40:00'); +TIME_TO_SEC('916:40:00') +3020399 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +SELECT ADDTIME('500:00:00', '416:40:00'); +ADDTIME('500:00:00', '416:40:00') +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +SELECT ADDTIME('916:40:00', '416:40:00'); +ADDTIME('916:40:00', '416:40:00') +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +Warning 1292 Truncated incorrect time value: '1255:39:59' +SELECT SUBTIME('916:40:00', '416:40:00'); +SUBTIME('916:40:00', '416:40:00') +422:19:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:40:00' +SELECT SUBTIME('-916:40:00', '416:40:00'); +SUBTIME('-916:40:00', '416:40:00') +-838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '-916:40:00' +Warning 1292 Truncated incorrect time value: '-1255:39:59' +SELECT MAKETIME(916,0,0); +MAKETIME(916,0,0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '916:00:00' +SELECT MAKETIME(4294967296, 0, 0); +MAKETIME(4294967296, 0, 0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '4294967296:00:00' +SELECT MAKETIME(-4294967296, 0, 0); +MAKETIME(-4294967296, 0, 0) +-838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '-4294967296:00:00' +SELECT MAKETIME(0, 4294967296, 0); +MAKETIME(0, 4294967296, 0) +NULL +SELECT MAKETIME(0, 0, 4294967296); +MAKETIME(0, 0, 4294967296) +NULL +SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); +MAKETIME(CAST(-1 AS UNSIGNED), 0, 0) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '18446744073709551615:00:00' +SELECT EXTRACT(HOUR FROM '100000:02:03'); +EXTRACT(HOUR FROM '100000:02:03') +838 +Warnings: +Warning 1292 Truncated incorrect time value: '100000:02:03' +CREATE TABLE t1(f1 TIME); +INSERT INTO t1 VALUES('916:00:00 a'); +Warnings: +Warning 1265 Data truncated for column 'f1' at row 1 +Warning 1264 Data truncated; out of range for column 'f1' at row 1 +SELECT * FROM t1; +f1 +838:59:59 +DROP TABLE t1; +SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); +SEC_TO_TIME(CAST(-1 AS UNSIGNED)) +838:59:59 +Warnings: +Warning 1292 Truncated incorrect time value: '18446744073709551615' +End of 4.1 tests diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index b232fb14e1e..d15aa9c9516 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -358,4 +358,47 @@ create table t1 select now() - now(), curtime() - curtime(), show create table t1; drop table t1; -# End of 4.1 tests +# +# Bug #11655: Wrong time is returning from nested selects - maximum time exists +# +# check if SEC_TO_TIME() handles out-of-range values correctly +SELECT SEC_TO_TIME(3300000); +SELECT SEC_TO_TIME(3300000)+0; +SELECT SEC_TO_TIME(3600 * 4294967296); + +# check if TIME_TO_SEC() handles out-of-range values correctly +SELECT TIME_TO_SEC('916:40:00'); + +# check if ADDTIME() handles out-of-range values correctly +SELECT ADDTIME('500:00:00', '416:40:00'); +SELECT ADDTIME('916:40:00', '416:40:00'); + +# check if SUBTIME() handles out-of-range values correctly +SELECT SUBTIME('916:40:00', '416:40:00'); +SELECT SUBTIME('-916:40:00', '416:40:00'); + +# check if MAKETIME() handles out-of-range values correctly +SELECT MAKETIME(916,0,0); +SELECT MAKETIME(4294967296, 0, 0); +SELECT MAKETIME(-4294967296, 0, 0); +SELECT MAKETIME(0, 4294967296, 0); +SELECT MAKETIME(0, 0, 4294967296); +SELECT MAKETIME(CAST(-1 AS UNSIGNED), 0, 0); + +# check if EXTRACT() handles out-of-range values correctly +SELECT EXTRACT(HOUR FROM '100000:02:03'); + +# check if we get proper warnings if both input string truncation +# and out-of-range value occur +CREATE TABLE t1(f1 TIME); +INSERT INTO t1 VALUES('916:00:00 a'); +SELECT * FROM t1; +DROP TABLE t1; + +# +# Bug #20927: sec_to_time treats big unsigned as signed +# +# check if SEC_TO_TIME() handles BIGINT UNSIGNED values correctly +SELECT SEC_TO_TIME(CAST(-1 AS UNSIGNED)); + +--echo End of 4.1 tests diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 3c46a944ba9..baf9a3902d9 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -402,8 +402,10 @@ err: There may be an optional [.second_part] after seconds length Length of str l_time Store result here - was_cut Set to 1 if value was cut during conversion or to 0 - otherwise. + warning Set MYSQL_TIME_WARN_TRUNCATED flag if the input string + was cut during conversion, and/or + MYSQL_TIME_WARN_OUT_OF_RANGE flag, if the value is + out of range. NOTES Because of the extra days argument, this function can only @@ -414,16 +416,16 @@ err: 1 error */ -bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, - int *was_cut) +bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, int *warning) { - long date[5],value; + ulong date[5]; + ulonglong value; const char *end=str+length, *end_of_days; bool found_days,found_hours; uint state; l_time->neg=0; - *was_cut= 0; + *warning= 0; for (; str != end && my_isspace(&my_charset_latin1,*str) ; str++) length--; if (str != end && *str == '-') @@ -438,13 +440,16 @@ bool str_to_time(const char *str, uint length, MYSQL_TIME *l_time, /* Check first if this is a full TIMESTAMP */ if (length >= 12) { /* Probably full timestamp */ + int was_cut; enum enum_mysql_timestamp_type res= str_to_datetime(str, length, l_time, - (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), was_cut); + (TIME_FUZZY_DATE | TIME_DATETIME_ONLY), &was_cut); if ((int) res >= (int) MYSQL_TIMESTAMP_ERROR) + { + if (was_cut) + *warning|= MYSQL_TIME_WARN_TRUNCATED; return res == MYSQL_TIMESTAMP_ERROR; - /* We need to restore was_cut flag since str_to_datetime can modify it */ - *was_cut= 0; + } } /* Not a timestamp. Try to get this as a DAYS_TO_SECOND string */ @@ -524,7 +529,7 @@ fractional: if (field_length > 0) value*= (long) log_10_int[field_length]; else if (field_length < 0) - *was_cut= 1; + *warning|= MYSQL_TIME_WARN_TRUNCATED; date[4]=value; } else @@ -538,10 +543,7 @@ fractional: ((str[1] == '-' || str[1] == '+') && (end - str) > 2 && my_isdigit(&my_charset_latin1, str[2])))) - { - *was_cut= 1; return 1; - } if (internal_format_positions[7] != 255) { @@ -560,12 +562,12 @@ fractional: } } - /* Some simple checks */ - if (date[2] >= 60 || date[3] >= 60) - { - *was_cut= 1; + /* Integer overflow checks */ + if (date[0] > UINT_MAX || date[1] > UINT_MAX || + date[2] > UINT_MAX || date[3] > UINT_MAX || + date[4] > UINT_MAX) return 1; - } + l_time->year= 0; /* For protocol::store_time */ l_time->month= 0; l_time->day= date[0]; @@ -575,6 +577,10 @@ fractional: l_time->second_part= date[4]; l_time->time_type= MYSQL_TIMESTAMP_TIME; + /* Check if the value is valid and fits into TIME range */ + if (check_time_range(l_time, warning)) + return 1; + /* Check if there is garbage at end of the TIME specification */ if (str != end) { @@ -582,7 +588,7 @@ fractional: { if (!my_isspace(&my_charset_latin1,*str)) { - *was_cut= 1; + *warning|= MYSQL_TIME_WARN_TRUNCATED; break; } } while (++str != end); @@ -591,6 +597,47 @@ fractional: } +/* + Check 'time' value to lie in the TIME range + + SYNOPSIS: + check_time_range() + time pointer to TIME value + warning set MYSQL_TIME_WARN_OUT_OF_RANGE flag if the value is out of range + + DESCRIPTION + If the time value lies outside of the range [-838:59:59, 838:59:59], + set it to the closest endpoint of the range and set + MYSQL_TIME_WARN_OUT_OF_RANGE flag in the 'warning' variable. + + RETURN + 0 time value is valid, but was possibly truncated + 1 time value is invalid +*/ + +int check_time_range(struct st_mysql_time *time, int *warning) +{ + longlong hour; + + if (time->minute >= 60 || time->second >= 60) + return 1; + + hour= time->hour + (24*time->day); + if (hour <= TIME_MAX_HOUR && + (hour != TIME_MAX_HOUR || time->minute != TIME_MAX_MINUTE || + time->second != TIME_MAX_SECOND || !time->second_part)) + return 0; + + time->day= 0; + time->hour= TIME_MAX_HOUR; + time->minute= TIME_MAX_MINUTE; + time->second= TIME_MAX_SECOND; + time->second_part= 0; + *warning|= MYSQL_TIME_WARN_OUT_OF_RANGE; + return 0; +} + + /* Prepare offset of system time zone from UTC for my_system_gmt_sec() func. @@ -776,7 +823,7 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type) int my_time_to_str(const MYSQL_TIME *l_time, char *to) { uint extra_hours= 0; - return my_sprintf(to, (to, "%s%02d:%02d:%02d", + return my_sprintf(to, (to, "%s%02u:%02u:%02u", (l_time->neg ? "-" : ""), extra_hours+ l_time->hour, l_time->minute, @@ -785,7 +832,7 @@ int my_time_to_str(const MYSQL_TIME *l_time, char *to) int my_date_to_str(const MYSQL_TIME *l_time, char *to) { - return my_sprintf(to, (to, "%04d-%02d-%02d", + return my_sprintf(to, (to, "%04u-%02u-%02u", l_time->year, l_time->month, l_time->day)); @@ -793,7 +840,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to) int my_datetime_to_str(const MYSQL_TIME *l_time, char *to) { - return my_sprintf(to, (to, "%04d-%02d-%02d %02d:%02d:%02d", + return my_sprintf(to, (to, "%04u-%02u-%02u %02u:%02u:%02u", l_time->year, l_time->month, l_time->day, diff --git a/sql/field.cc b/sql/field.cc index 3cb0c0d3a7c..484758fb0e7 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -3961,9 +3961,10 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) { TIME ltime; long tmp; - int error; + int error= 0; + int warning; - if (str_to_time(from, len, <ime, &error)) + if (str_to_time(from, len, <ime, &warning)) { tmp=0L; error= 2; @@ -3972,29 +3973,27 @@ int Field_time::store(const char *from,uint len,CHARSET_INFO *cs) } else { - if (error) + if (warning & MYSQL_TIME_WARN_TRUNCATED) set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, from, len, MYSQL_TIMESTAMP_TIME, 1); - - if (ltime.month) - ltime.day=0; - tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); - if (tmp > 8385959) + if (warning & MYSQL_TIME_WARN_OUT_OF_RANGE) { - tmp=8385959; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, from, len, MYSQL_TIMESTAMP_TIME, !error); error= 1; } + if (ltime.month) + ltime.day=0; + tmp=(ltime.day*24L+ltime.hour)*10000L+(ltime.minute*100+ltime.second); if (error > 1) error= 2; } if (ltime.neg) tmp= -tmp; - error |= Field_time::store((longlong) tmp); + int3store(ptr,tmp); return error; } @@ -4003,16 +4002,16 @@ int Field_time::store(double nr) { long tmp; int error= 0; - if (nr > 8385959.0) + if (nr > (double)TIME_MAX_VALUE) { - tmp=8385959L; + tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; } - else if (nr < -8385959.0) + else if (nr < (double)-TIME_MAX_VALUE) { - tmp= -8385959L; + tmp= -TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME); error= 1; @@ -4040,17 +4039,17 @@ int Field_time::store(longlong nr) { long tmp; int error= 0; - if (nr > (longlong) 8385959L) + if (nr > (longlong) TIME_MAX_VALUE) { - tmp=8385959L; + tmp= TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); error= 1; } - else if (nr < (longlong) -8385959L) + else if (nr < (longlong) -TIME_MAX_VALUE) { - tmp= -8385959L; + tmp= -TIME_MAX_VALUE; set_datetime_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, nr, MYSQL_TIMESTAMP_TIME, 1); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2da0e8956c2..80e4cf8d456 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -95,6 +95,124 @@ static bool make_datetime(date_time_format_types format, TIME *ltime, } +/* + Wrapper over make_datetime() with validation of the input TIME value + + NOTE + see make_datetime() for more information + + RETURN + 1 if there was an error during converion + 0 otherwise +*/ + +static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime, + String *str) +{ + int warning= 0; + bool rc; + + if (make_datetime(format, ltime, str)) + return 1; + if (check_time_range(ltime, &warning)) + return 1; + if (!warning) + return 0; + + make_truncated_value_warning(current_thd, str->ptr(), str->length(), + MYSQL_TIMESTAMP_TIME); + return make_datetime(format, ltime, str); +} + + +/* + Wrapper over make_time() with validation of the input TIME value + + NOTE + see make_time() for more info + + RETURN + 1 if there was an error during conversion + 0 otherwise +*/ + +static bool make_time_with_warn(const DATE_TIME_FORMAT *format, + TIME *l_time, String *str) +{ + int warning= 0; + make_time(format, l_time, str); + if (check_time_range(l_time, &warning)) + return 1; + if (warning) + { + make_truncated_value_warning(current_thd, str->ptr(), str->length(), + MYSQL_TIMESTAMP_TIME); + make_time(format, l_time, str); + } + + return 0; +} + + +/* + Convert seconds to TIME value with overflow checking + + SYNOPSIS: + sec_to_time() + seconds number of seconds + unsigned_flag 1, if 'seconds' is unsigned, 0, otherwise + ltime output TIME value + + DESCRIPTION + If the 'seconds' argument is inside TIME data range, convert it to a + corresponding value. + Otherwise, truncate the resulting value to the nearest endpoint, and + produce a warning message. + + RETURN + 1 if the value was truncated during conversion + 0 otherwise +*/ + +static bool sec_to_time(longlong seconds, bool unsigned_flag, TIME *ltime) +{ + uint sec; + + bzero((char *)ltime, sizeof(*ltime)); + + if (seconds < 0) + { + if (unsigned_flag) + goto overflow; + ltime->neg= 1; + if (seconds < -3020399) + goto overflow; + seconds= -seconds; + } + else if (seconds > 3020399) + goto overflow; + + sec= (uint) ((ulonglong) seconds % 3600); + ltime->hour= (uint) (seconds/3600); + ltime->minute= sec/60; + ltime->second= sec % 60; + + return 0; + +overflow: + ltime->hour= TIME_MAX_HOUR; + ltime->minute= TIME_MAX_MINUTE; + ltime->second= TIME_MAX_SECOND; + + char buf[22]; + int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10) + - buf); + make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME); + + return 1; +} + + /* Date formats corresponding to compound %r and %T conversion specifiers @@ -1487,8 +1605,6 @@ int Item_func_now::save_in_field(Field *to, bool no_conversions) String *Item_func_sec_to_time::val_str(String *str) { DBUG_ASSERT(fixed == 1); - longlong seconds=(longlong) args[0]->val_int(); - uint sec; TIME ltime; if ((null_value=args[0]->null_value) || str->alloc(19)) @@ -1497,19 +1613,8 @@ String *Item_func_sec_to_time::val_str(String *str) return (String*) 0; } - ltime.neg= 0; - if (seconds < 0) - { - seconds= -seconds; - ltime.neg= 1; - } - - sec= (uint) ((ulonglong) seconds % 3600); - ltime.day= 0; - ltime.hour= (uint) (seconds/3600); - ltime.minute= sec/60; - ltime.second= sec % 60; - + sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime); + make_time((DATE_TIME_FORMAT *) 0, <ime, str); return str; } @@ -1518,16 +1623,15 @@ String *Item_func_sec_to_time::val_str(String *str) longlong Item_func_sec_to_time::val_int() { DBUG_ASSERT(fixed == 1); - longlong seconds=args[0]->val_int(); - longlong sign=1; + TIME ltime; + if ((null_value=args[0]->null_value)) return 0; - if (seconds < 0) - { - seconds= -seconds; - sign= -1; - } - return sign*((seconds / 3600)*10000+((seconds/60) % 60)*100+ (seconds % 60)); + + sec_to_time(args[0]->val_int(), args[0]->unsigned_flag, <ime); + + return (ltime.neg ? -1 : 1) * + ((ltime.hour)*10000 + ltime.minute*100 + ltime.second); } @@ -2531,7 +2635,9 @@ String *Item_func_add_time::val_str(String *str) } if (l_time1.neg != l_time2.neg) l_sign= -l_sign; - + + bzero((char *)&l_time3, sizeof(l_time3)); + l_time3.neg= calc_time_diff(&l_time1, &l_time2, -l_sign, &seconds, µseconds); @@ -2560,9 +2666,9 @@ String *Item_func_add_time::val_str(String *str) } l_time3.hour+= days*24; - if (!make_datetime(l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY, - &l_time3, str)) + if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY, + &l_time3, str)) return str; null_date: @@ -2617,6 +2723,8 @@ String *Item_func_timediff::val_str(String *str) if (l_time1.neg != l_time2.neg) l_sign= -l_sign; + bzero((char *)&l_time3, sizeof(l_time3)); + l_time3.neg= calc_time_diff(&l_time1, &l_time2, l_sign, &seconds, µseconds); @@ -2630,9 +2738,9 @@ String *Item_func_timediff::val_str(String *str) calc_time_from_sec(&l_time3, (long) seconds, microseconds); - if (!make_datetime(l_time1.second_part || l_time2.second_part ? - TIME_MICROSECOND : TIME_ONLY, - &l_time3, str)) + if (!make_datetime_with_warn(l_time1.second_part || l_time2.second_part ? + TIME_MICROSECOND : TIME_ONLY, + &l_time3, str)) return str; null_date: @@ -2650,29 +2758,57 @@ String *Item_func_maketime::val_str(String *str) { DBUG_ASSERT(fixed == 1); TIME ltime; + bool overflow= 0; - long hour= (long) args[0]->val_int(); - long minute= (long) args[1]->val_int(); - long second= (long) args[2]->val_int(); + longlong hour= args[0]->val_int(); + longlong minute= args[1]->val_int(); + longlong second= args[2]->val_int(); if ((null_value=(args[0]->null_value || - args[1]->null_value || - args[2]->null_value || - minute > 59 || minute < 0 || - second > 59 || second < 0 || - str->alloc(19)))) + args[1]->null_value || + args[2]->null_value || + minute < 0 || minute > 59 || + second < 0 || second > 59 || + str->alloc(19)))) return 0; + bzero((char *)<ime, sizeof(ltime)); ltime.neg= 0; + + /* Check for integer overflows */ if (hour < 0) { - ltime.neg= 1; - hour= -hour; + if (args[0]->unsigned_flag) + overflow= 1; + else + ltime.neg= 1; + } + if (-hour > UINT_MAX || hour > UINT_MAX) + overflow= 1; + + if (!overflow) + { + ltime.hour= (uint) ((hour < 0 ? -hour : hour)); + ltime.minute= (uint) minute; + ltime.second= (uint) second; + } + else + { + ltime.hour= TIME_MAX_HOUR; + ltime.minute= TIME_MAX_MINUTE; + ltime.second= TIME_MAX_SECOND; + char buf[28]; + char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10); + int len = (int)(ptr - buf) + + my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second)); + make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME); + } + + if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str)) + { + null_value= 1; + return 0; } - ltime.hour= (ulong) hour; - ltime.minute= (ulong) minute; - ltime.second= (ulong) second; - make_time((DATE_TIME_FORMAT *) 0, <ime, str); return str; } @@ -2878,7 +3014,7 @@ bool Item_func_str_to_date::get_date(TIME *ltime, uint fuzzy_date) goto null_date; null_value= 0; - bzero((char*) ltime, sizeof(ltime)); + bzero((char*) ltime, sizeof(*ltime)); date_time_format.format.str= (char*) format->ptr(); date_time_format.format.length= format->length(); if (extract_date_time(&date_time_format, val->ptr(), val->length(), diff --git a/sql/time.cc b/sql/time.cc index ef832ac5a70..ddc5e6435be 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -255,9 +255,9 @@ my_time_t TIME_to_timestamp(THD *thd, const TIME *t, bool *in_dst_time_gap) bool str_to_time_with_warn(const char *str, uint length, TIME *l_time) { - int was_cut; - bool ret_val= str_to_time(str, length, l_time, &was_cut); - if (was_cut) + int warning; + bool ret_val= str_to_time(str, length, l_time, &warning); + if (ret_val || warning) make_truncated_value_warning(current_thd, str, length, MYSQL_TIMESTAMP_TIME); return ret_val; } From e5d14529bc1a6a542130859714d6ae505197266c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 16:28:23 +0200 Subject: [PATCH 042/235] Fixup the regex's parsing the mysqld's version and variables Add paths for ndb binaries Some more backport issues mysql-test/include/have_ndb.inc: Remove the check for NDB_STATUS_OK, handled by mysql-test-run.pl --- mysql-test/include/have_ndb.inc | 1 - mysql-test/mysql-test-run.pl | 104 ++++++++++++++++++++++++-------- 2 files changed, 78 insertions(+), 27 deletions(-) diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index 9b85197abe8..84e60657876 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -1,4 +1,3 @@ ---exec test x$NDB_STATUS_OK = x1 -- require r/have_ndb.require disable_query_log; show variables like "have_ndbcluster"; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 39c116a3fcb..3ad083dbd0c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1141,7 +1141,7 @@ sub check_mysqld_features () { # print out version and a list of all features and settings # my $found_variable_list_start= 0; - my $spec_file= "$opt_vardir/tmp/mysqld.spec"; + my $spec_file= "$opt_vardir/mysqld.spec"; if ( mtr_run($exe_mysqld, ["--no-defaults", "--verbose", @@ -1174,20 +1174,31 @@ sub check_mysqld_features () { if (!$found_variable_list_start) { # Look for start of variables list - if ( $line =~ /-*\s-*/ ) + if ( $line =~ /[\-]+\s[\-]+/ ) { $found_variable_list_start= 1; } - } else { + } + else + { # Put variables into hash - if ( $line =~ /^(\w*)[ \t]*(\w*)$/ ) + if ( $line =~ /^([\S]+)[ \t]+(.*)$/ ) { + # print "$1=$2\n"; $mysqld_variables{$1}= $2; } + else + { + # The variable list is ended with a blank line, so when a line + # doesn't match the above regex, break the loop + last; + } } } } + unlink($spec_file); mtr_error("Could not find version of MySQL") unless $mysql_version_id; + mtr_error("Could not find variabes list") unless $found_variable_list_start; check_ndbcluster_support(\%mysqld_variables); check_ssl_support(\%mysqld_variables); @@ -1197,6 +1208,14 @@ sub check_mysqld_features () { { # Instance manager is not supported until 5.0 $opt_skip_im= 1; + + } + + if ( $mysql_version_id < 50100 ) + { + # Slave cluster is not supported until 5.1 + $opt_skip_ndbcluster_slave= 1; + } # Set default values from mysqld_variables @@ -1294,13 +1313,26 @@ sub executable_setup () { mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", "$path_client_bindir/mysql_fix_privilege_tables"); - if ( $opt_with_ndbcluster) + if ( ! $opt_skip_ndbcluster) { # Look for ndb tols and binaries - $path_ndb_tools_dir= mtr_path_exists("$glob_basedir/ndb/tools", + my $ndb_path= mtr_path_exists("$glob_basedir/ndb", + "$glob_basedir/storage/ndb"); + + $path_ndb_tools_dir= mtr_path_exists("$ndb_path/tools", "$glob_basedir/bin"); - $exe_ndb_mgm= mtr_exe_exists("$glob_basedir/ndb/src/mgmclient/ndb_mgm", - "$glob_basedir/bin/ndb_mgm"); + $exe_ndb_mgm= + mtr_exe_exists("$ndb_path/src/mgmclient/ndb_mgm", + "$glob_basedir/bin/ndb_mgm"); + $exe_ndb_mgmd= + mtr_exe_exists("$ndb_path/src/mgmsrv/ndb_mgmd", + "$glob_basedir/bin/ndb_mgmd"); + $exe_ndb_waiter= + mtr_exe_exists("$ndb_path/tools/ndb_waiter", + "$glob_basedir/bin/ndb_waiter"); + $exe_ndbd= + mtr_exe_exists("$ndb_path/src/kernel/ndbd", + "$glob_basedir/bin/ndbd"); } # Look for the udf_example library @@ -1616,7 +1648,8 @@ sub environment_setup () { # Setup env so childs can execute mysql_fix_system_tables # ---------------------------------------------------- my $cmdline_mysql_fix_system_tables= - "$exe_mysql_fix_system_tables --no-defaults --host=localhost --user=root --password= " . + "$exe_mysql_fix_system_tables --no-defaults --host=localhost " . + "--user=root --password= " . "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'}"; @@ -1832,7 +1865,7 @@ sub check_ssl_support ($) { return; } - if ( $mysqld_variables->{'ssl'} eq "FALSE" ) + if ( ! $mysqld_variables->{'ssl'} ) { if ( $opt_ssl) { @@ -1883,7 +1916,7 @@ sub check_ndbcluster_support ($) { return; } - if ( $mysqld_variables->{'ndbcluster'} eq "FALSE") + if ( ! $mysqld_variables->{'ndb-connectstring'} ) { mtr_report("Skipping ndbcluster, mysqld not compiled with ndbcluster"); $opt_skip_ndbcluster= 1; @@ -1949,6 +1982,11 @@ sub ndbcluster_start_install ($) { s/CHOOSE_HOSTNAME_.*/$ndb_host/; s/CHOOSE_FILESYSTEM/$cluster->{'data_dir'}/; s/CHOOSE_PORT_MGM/$cluster->{'port'}/; + if ( $mysql_version_id < 50000 ) + { + my $base_port= $cluster->{'port'} + 1; + s/CHOOSE_PORT_TRANSPORTER/$base_port/; + } s/CHOOSE_DiskPageBufferMemory/$ndb_pbmem/; print OUT "$_ \n"; @@ -2070,7 +2108,10 @@ sub ndbd_start ($$$) { mtr_add_arg($args, "--no-defaults"); mtr_add_arg($args, "--core"); mtr_add_arg($args, "--ndb-connectstring=%s", "$cluster->{'connect_string'}"); - mtr_add_arg($args, "--character-sets-dir=%s", "$path_charsetsdir"); + if ( $mysql_version_id >= 50000) + { + mtr_add_arg($args, "--character-sets-dir=%s", "$path_charsetsdir"); + } mtr_add_arg($args, "--nodaemon"); mtr_add_arg($args, "$extra_args"); @@ -2247,8 +2288,6 @@ sub run_suite () { mtr_report_stats($tests); -# Look for testname.warning files if --do-test= - mtr_timer_stop($glob_timers,"suite"); } @@ -2298,7 +2337,8 @@ sub mysql_install_db () { my $cluster_started_ok= 1; # Assume it can be started if (ndbcluster_start_install($clusters->[0]) || - $max_slave_num && ndbcluster_start_install($clusters->[1])) + ($max_slave_num && !$opt_skip_ndbcluster_slave && + ndbcluster_start_install($clusters->[1]))) { mtr_warning("Failed to start install of cluster"); $cluster_started_ok= 0; @@ -2986,7 +3026,10 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--ndbcluster", $prefix); mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, $cluster->{'connect_string'}); - mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + if ( $mysql_version_id >= 50000 ) + { + mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + } } } @@ -3061,7 +3104,10 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--ndbcluster", $prefix); mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, $clusters->[$slave->[$idx]->{'cluster'}]->{'connect_string'}); - mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + if ( $mysql_version_id >= 50000 ) + { + mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); + } } } # end slave @@ -3646,16 +3692,21 @@ sub run_testcase_start_servers($) { { # Test needs cluster, start an extra mysqld connected to cluster - # First wait for first mysql server to have created ndb system tables ok - # FIXME This is a workaround so that only one mysqld creates the tables - if ( ! sleep_until_file_created( - "$master->[0]->{'path_myddir'}/cluster/apply_status.ndb", - $master->[0]->{'start_timeout'}, - $master->[0]->{'pid'})) + if ( $mysql_version_id >= 50100 ) { - mtr_report("Failed to create 'cluster/apply_status' table"); - report_failure_and_restart($tinfo); - return; + # First wait for first mysql server to have created ndb system + # tables ok FIXME This is a workaround so that only one mysqld + # create the tables + if ( ! sleep_until_file_created( + "$master->[0]->{'path_myddir'}/cluster/apply_status.ndb", + $master->[0]->{'start_timeout'}, + $master->[0]->{'pid'})) + { + mtr_report_test_name($tinfo); + mtr_report("Failed to create 'cluster/apply_status' table"); + report_failure_and_restart($tinfo); + return; + } } mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); @@ -3679,6 +3730,7 @@ sub run_testcase_start_servers($) { unless ( mtr_im_start($instance_manager, $tinfo->{im_opts}) ) { + mtr_report_test_name($tinfo); report_failure_and_restart($tinfo); mtr_report("Failed to start Instance Manager. " . "The test '$tname' is marked as failed."); From aaef575f9f360e03f344d55f5f14aacff382ce2c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 10:49:39 -0400 Subject: [PATCH 043/235] Bug #19024- SHOW COUNT(*) WARNINGS not return Errors The server variable warning_count should include the number of warnings, errors and notes according to the manual mysql-test/r/user_var.result: Added warning_count results. mysql-test/t/user_var.test: Added test case for warning_count. sql/set_var.cc: Added number errors to warning_count. --- mysql-test/r/user_var.result | 9 +++++++++ mysql-test/t/user_var.test | 10 +++++++++- sql/set_var.cc | 1 + 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 1664a907c99..90954fc1ede 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -215,6 +215,7 @@ select @@version; select @@global.version; @@global.version # +End of 4.1 tests set @first_var= NULL; create table t1 select @first_var; show create table t1; @@ -301,3 +302,11 @@ select @var; @var 3 drop table t1; +insert into city 'blah'; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''blah'' at line 1 +SHOW COUNT(*) WARNINGS; +@@session.warning_count +1 +SHOW COUNT(*) ERRORS; +@@session.error_count +1 diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index 644ca506eba..65ca1b2c1b7 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -144,6 +144,8 @@ select @@version; --replace_column 1 # select @@global.version; +--echo End of 4.1 tests + # Bug #6598: problem with cast(NULL as signed integer); # @@ -210,4 +212,10 @@ select @var:=f2 from t1 group by f1 order by f2 desc limit 1; select @var; drop table t1; -# End of 4.1 tests +# +# Bug#19024 - SHOW COUNT(*) WARNINGS not return Errors +# +--error 1064 +insert into city 'blah'; +SHOW COUNT(*) WARNINGS; +SHOW COUNT(*) ERRORS; diff --git a/sql/set_var.cc b/sql/set_var.cc index c667e2f2bcc..dd41256a7cc 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2917,6 +2917,7 @@ static byte *get_warning_count(THD *thd) { thd->sys_var_tmp.long_value= (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] + + thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] + thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]); return (byte*) &thd->sys_var_tmp.long_value; } From f60ea28841ee37627e1997850ad0a5c5bd311bc2 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 11:19:23 -0400 Subject: [PATCH 044/235] Bug#19356: Assert on undefined @uservar in prepared statement execute The executing code had a safety assertion so that it refused to free Items that it didn't create. However, there is a case, undefined user variables, which would put Items into the list to be freed. Instead, do something that is more risky in expectation that the code will be refactored soon, as Kostja wants to do: Remove the assertions from prepare() and execute(). Put one assertion at a higher level, before stmt->set_params_from_vars(), which may then create new to-be-freed Items . mysql-test/r/ps_11bugs.result: Create tests to prove that undefined variables work, as keys and not, and that variables explicitly assigned to Null work. mysql-test/t/ps_11bugs.test: Create tests to prove that undefined variables work, as keys and not, and that variables explicitly assigned to Null work. sql/sql_prepare.cc: Move a safety assertion up one level and higher, because there is legitimately a case where thd->free_list is not NULL going into Prepared_statement::{prepare,execute} methods. Kostja plans to refactor this code so that it is both safe and works. (Now it works, but isn't very safe.) --- BitKeeper/etc/collapsed | 2 ++ mysql-test/r/ps_11bugs.result | 33 +++++++++++++++++++++++++++++++++ mysql-test/t/ps_11bugs.test | 34 ++++++++++++++++++++++++++++++++++ sql/sql_prepare.cc | 33 +++++++++++++++++++++++++++------ 4 files changed, 96 insertions(+), 6 deletions(-) diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed index d4d681937a2..7a682f9b2c0 100644 --- a/BitKeeper/etc/collapsed +++ b/BitKeeper/etc/collapsed @@ -2,3 +2,5 @@ 44ec850ac2k4y2Omgr92GiWPBAVKGQ 44edb86b1iE5knJ97MbliK_3lCiAXA 44f33f3aj5KW5qweQeekY1LU0E9ZCg +45214442pBGT9KuZEGixBH71jTzbOA +45214a07hVsIGwvwa-WrO-jpeaSwVw diff --git a/mysql-test/r/ps_11bugs.result b/mysql-test/r/ps_11bugs.result index c849c25d646..ebe161f46b3 100644 --- a/mysql-test/r/ps_11bugs.result +++ b/mysql-test/r/ps_11bugs.result @@ -130,3 +130,36 @@ prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1) execute st_18492; a drop table t1; +create table t1 (a int, b varchar(4)); +create table t2 (a int, b varchar(4), primary key(a)); +prepare stmt1 from 'insert into t1 (a, b) values (?, ?)'; +prepare stmt2 from 'insert into t2 (a, b) values (?, ?)'; +set @intarg= 11; +set @varchararg= '2222'; +execute stmt1 using @intarg, @varchararg; +execute stmt2 using @intarg, @varchararg; +set @intarg= 12; +execute stmt1 using @intarg, @UNDEFINED; +execute stmt2 using @intarg, @UNDEFINED; +set @intarg= 13; +execute stmt1 using @UNDEFINED, @varchararg; +execute stmt2 using @UNDEFINED, @varchararg; +ERROR 23000: Column 'a' cannot be null +set @intarg= 14; +set @nullarg= Null; +execute stmt1 using @UNDEFINED, @nullarg; +execute stmt2 using @nullarg, @varchararg; +ERROR 23000: Column 'a' cannot be null +select * from t1; +a b +11 2222 +12 NULL +NULL 2222 +NULL NULL +select * from t2; +a b +11 2222 +12 NULL +drop table t1; +drop table t2; +End of 5.0 tests. diff --git a/mysql-test/t/ps_11bugs.test b/mysql-test/t/ps_11bugs.test index ff1c87f3bd8..515bcc03c1a 100644 --- a/mysql-test/t/ps_11bugs.test +++ b/mysql-test/t/ps_11bugs.test @@ -144,3 +144,37 @@ prepare st_18492 from 'select * from t1 where 3 in (select (1+1) union select 1) execute st_18492; drop table t1; + +# +# Bug#19356: Assertion failure with undefined @uservar in prepared statement execution +# +create table t1 (a int, b varchar(4)); +create table t2 (a int, b varchar(4), primary key(a)); + +prepare stmt1 from 'insert into t1 (a, b) values (?, ?)'; +prepare stmt2 from 'insert into t2 (a, b) values (?, ?)'; + +set @intarg= 11; +set @varchararg= '2222'; +execute stmt1 using @intarg, @varchararg; +execute stmt2 using @intarg, @varchararg; +set @intarg= 12; +execute stmt1 using @intarg, @UNDEFINED; +execute stmt2 using @intarg, @UNDEFINED; +set @intarg= 13; +execute stmt1 using @UNDEFINED, @varchararg; +--error 1048 +execute stmt2 using @UNDEFINED, @varchararg; +set @intarg= 14; +set @nullarg= Null; +execute stmt1 using @UNDEFINED, @nullarg; +--error 1048 +execute stmt2 using @nullarg, @varchararg; + +select * from t1; +select * from t2; + +drop table t1; +drop table t2; + +--echo End of 5.0 tests. diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 32f0ca6859d..9e321411863 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2248,6 +2248,14 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length) #endif if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(),QUERY_PRIOR); + + /* + If the free_list is not empty, we'll wrongly free some externally + allocated items when cleaning up after validation of the prepared + statement. + */ + DBUG_ASSERT(thd->free_list == NULL); + error= stmt->execute(&expanded_query, test(flags & (ulong) CURSOR_TYPE_READ_ONLY)); if (!(specialflag & SPECIAL_NO_PRIOR)) @@ -2310,6 +2318,13 @@ void mysql_sql_stmt_execute(THD *thd) DBUG_PRINT("info",("stmt: %p", stmt)); + /* + If the free_list is not empty, we'll wrongly free some externally + allocated items when cleaning up after validation of the prepared + statement. + */ + DBUG_ASSERT(thd->free_list == NULL); + if (stmt->set_params_from_vars(stmt, lex->prepared_stmt_params, &expanded_query)) goto set_params_data_err; @@ -2788,12 +2803,12 @@ bool Prepared_statement::prepare(const char *packet, uint packet_len) external changes when cleaning up after validation. */ DBUG_ASSERT(thd->change_list.is_empty()); - /* - If the free_list is not empty, we'll wrongly free some externally - allocated items when cleaning up after validation of the prepared - statement. + + /* + The only case where we should have items in the thd->free_list is + after stmt->set_params_from_vars(), which may in some cases create + Item_null objects. */ - DBUG_ASSERT(thd->free_list == NULL); if (error == 0) error= check_prepared_statement(this, name.str != 0); @@ -2891,7 +2906,13 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) allocated items when cleaning up after execution of this statement. */ DBUG_ASSERT(thd->change_list.is_empty()); - DBUG_ASSERT(thd->free_list == NULL); + + /* + The only case where we should have items in the thd->free_list is + after stmt->set_params_from_vars(), which may in some cases create + Item_null objects. + */ + thd->set_n_backup_statement(this, &stmt_backup); if (expanded_query->length() && alloc_query(thd, (char*) expanded_query->ptr(), From 091de56e601023fa373921d62f6670700b4d6ef8 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 18:48:22 +0200 Subject: [PATCH 045/235] --ndb-extra-logging option to mysqld is not available until 5.1 --- mysql-test/mysql-test-run.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3ad083dbd0c..91e2920ff19 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3026,7 +3026,7 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--ndbcluster", $prefix); mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, $cluster->{'connect_string'}); - if ( $mysql_version_id >= 50000 ) + if ( $mysql_version_id >= 50100 ) { mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); } @@ -3104,7 +3104,7 @@ sub mysqld_arguments ($$$$$) { mtr_add_arg($args, "%s--ndbcluster", $prefix); mtr_add_arg($args, "%s--ndb-connectstring=%s", $prefix, $clusters->[$slave->[$idx]->{'cluster'}]->{'connect_string'}); - if ( $mysql_version_id >= 50000 ) + if ( $mysql_version_id >= 50100 ) { mtr_add_arg($args, "%s--ndb-extra-logging", $prefix); } From 3f45e43c06705846f54264c1b28ab9c9b6e702ff Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 19:21:22 +0200 Subject: [PATCH 046/235] Create the mysqld.spec file with a unique name in mysql-test dir, $opt_var_dir haven't been created yet --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 91e2920ff19..1305d9d59e6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1141,7 +1141,7 @@ sub check_mysqld_features () { # print out version and a list of all features and settings # my $found_variable_list_start= 0; - my $spec_file= "$opt_vardir/mysqld.spec"; + my $spec_file= "$glob_mysql_test_dir/mysqld.spec.$$"; if ( mtr_run($exe_mysqld, ["--no-defaults", "--verbose", From fe8d349ad99089cf349dae6cfc230af71cc05a7f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 22:50:34 +0200 Subject: [PATCH 047/235] Set slave_load_path to ../../var/tmp in version prior to 5.0 to be compatible with mysql-test-run.sh --- mysql-test/mysql-test-run.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1305d9d59e6..108a97f03b4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3068,8 +3068,13 @@ sub mysqld_arguments ($$$$$) { # Directory where slaves find the dumps generated by "load data" # on the server. The path need to have constant length otherwise # test results will vary, thus a relative path is used. + my $slave_load_path= "../tmp"; + if ( $mysql_version_id < 50000 ) + { + $slave_load_path= "../../var/tmp"; + } mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix, - "../tmp"); + $slave_load_path); mtr_add_arg($args, "%s--socket=%s", $prefix, $slave->[$idx]->{'path_sock'}); mtr_add_arg($args, "%s--set-variable=slave_net_timeout=10", $prefix); From ca25d07ee5714182c4a54ad638ac89b472a01a55 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 22:52:44 +0200 Subject: [PATCH 048/235] Use replace_regex to mask the output of file_id= in "show binlog events" that depends on previous tests What is this? replace_regex in 4.1! :) mysql-test/r/rpl_charset.result: Use replace_regex to mask the output of file_id= in "show binlog events" that depends on previous tests mysql-test/t/rpl_charset.test: Use replace_regex to mask the output of file_id= in "show binlog events" that depends on previous tests --- mysql-test/r/rpl_charset.result | 4 ++-- mysql-test/t/rpl_charset.test | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/rpl_charset.result b/mysql-test/r/rpl_charset.result index 292cfb19175..0ebd97d0b6a 100644 --- a/mysql-test/r/rpl_charset.result +++ b/mysql-test/r/rpl_charset.result @@ -147,10 +147,10 @@ master-bin.000001 3577 Intvar 1 3577 INSERT_ID=4 master-bin.000001 3605 Query 1 3605 use `mysqltest2`; insert into t1 (b) values(LEAST("Müller","Muffler")) master-bin.000001 3698 Query 1 3698 use `mysqltest2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 master-bin.000001 3839 Intvar 1 3839 INSERT_ID=74 -master-bin.000001 3867 Create_file 1 3867 db=mysqltest2;table=t1;file_id=1;block_len=581 +master-bin.000001 3867 Create_file 1 3867 db=mysqltest2;table=t1;file_id=x;block_len=581 master-bin.000001 4540 Query 1 4540 use `mysqltest2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 master-bin.000001 4681 Intvar 1 4681 INSERT_ID=5 -master-bin.000001 4709 Exec_load 1 4709 ;file_id=1 +master-bin.000001 4709 Exec_load 1 4709 ;file_id=x master-bin.000001 4732 Query 1 4732 use `mysqltest2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 master-bin.000001 4873 Query 1 4873 use `mysqltest2`; truncate table t1 master-bin.000001 4931 Query 1 4931 use `mysqltest2`; SET ONE_SHOT CHARACTER_SET_CLIENT=8,COLLATION_CONNECTION=31,COLLATION_DATABASE=9,COLLATION_SERVER=64 diff --git a/mysql-test/t/rpl_charset.test b/mysql-test/t/rpl_charset.test index cf079048fc3..a6f4c2ba9be 100644 --- a/mysql-test/t/rpl_charset.test +++ b/mysql-test/t/rpl_charset.test @@ -106,6 +106,8 @@ select * from mysqltest2.t1 order by a; connection master; drop database mysqltest2; drop database mysqltest3; +# file_id: xx can vary depending on previous tests +--replace_regex /file_id=[0-9]/file_id=x/ show binlog events from 79; sync_slave_with_master; From d7b6fdcd6cd17826145773fd1ab352354f5192c5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:05:12 +0200 Subject: [PATCH 049/235] Clean up de_before_start_master/slave --- mysql-test/mysql-test-run.pl | 57 +++++++++++++----------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 108a97f03b4..1d3c0ff1dd4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -360,8 +360,8 @@ sub run_testcase_stop_servers ($$$); sub run_testcase_start_servers ($); sub run_testcase_check_skip_test($); sub report_failure_and_restart ($); -sub do_before_start_master ($$); -sub do_before_start_slave ($$); +sub do_before_start_master ($); +sub do_before_start_slave ($); sub ndbd_start ($$$); sub ndb_mgmd_start ($); sub mysqld_start ($$$); @@ -2866,24 +2866,17 @@ sub report_failure_and_restart ($) { ############################################################################## -# The embedded server needs the cleanup so we do some of the start work -# but stop before actually running mysqld or anything. -sub do_before_start_master ($$) { - my $tname= shift; - my $init_script= shift; +sub do_before_start_master ($) { + my ($tinfo)= @_; + + my $tname= $tinfo->{'name'}; + my $init_script= $tinfo->{'master_sh'}; # FIXME what about second master..... - # Remove stale binary logs except for 2 tests which need them FIXME here???? - if ( $tname ne "rpl_crash_binlog_ib_1b" and - $tname ne "rpl_crash_binlog_ib_2b" and - $tname ne "rpl_crash_binlog_ib_3b") + foreach my $bin ( glob("$opt_vardir/log/master*-bin*") ) { - # FIXME we really want separate dir for binlogs - foreach my $bin ( glob("$opt_vardir/log/master*-bin*") ) - { - unlink($bin); - } + unlink($bin); } # FIXME only remove the ones that are tied to this master @@ -2903,31 +2896,23 @@ sub do_before_start_master ($$) { # mtr_warning("$init_script exited with code $ret"); } } - # for gcov FIXME needed? If so we need more absolute paths - # chdir($glob_basedir); } -sub do_before_start_slave ($$) { - my $tname= shift; - my $init_script= shift; +sub do_before_start_slave ($) { + my ($tinfo)= @_; - # Remove stale binary logs and old master.info files - # except for too tests which need them - if ( $tname ne "rpl_crash_binlog_ib_1b" and - $tname ne "rpl_crash_binlog_ib_2b" and - $tname ne "rpl_crash_binlog_ib_3b" ) + my $tname= $tinfo->{'name'}; + my $init_script= $tinfo->{'master_sh'}; + + foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") ) { - # FIXME we really want separate dir for binlogs - foreach my $bin ( glob("$opt_vardir/log/slave*-bin*") ) - { - unlink($bin); - } - # FIXME really master?! - unlink("$slave->[0]->{'path_myddir'}/master.info"); - unlink("$slave->[0]->{'path_myddir'}/relay-log.info"); + unlink($bin); } + unlink("$slave->[0]->{'path_myddir'}/master.info"); + unlink("$slave->[0]->{'path_myddir'}/relay-log.info"); + # Run slave initialization shell script if one exists if ( $init_script ) { @@ -3687,7 +3672,7 @@ sub run_testcase_start_servers($) { if ( !$master->[0]->{'pid'} ) { # Master mysqld is not started - do_before_start_master($tname,$tinfo->{'master_sh'}); + do_before_start_master($tinfo); mysqld_start($master->[0],$tinfo->{'master_opt'},[]); @@ -3752,7 +3737,7 @@ sub run_testcase_start_servers($) { restore_slave_databases($tinfo->{'slave_num'}); - do_before_start_slave($tname,$tinfo->{'slave_sh'}); + do_before_start_slave($tinfo); if ( ! $opt_skip_ndbcluster_slave and !$clusters->[1]->{'pid'} and From 4e75b447491fbe01df33a03dec54ca761bffba95 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:07:49 +0200 Subject: [PATCH 050/235] Use switch --old-log-format to mysqld started by im only in 5.1 and up --- mysql-test/mysql-test-run.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1d3c0ff1dd4..a2a840208da 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2539,7 +2539,10 @@ EOF ; print OUT "nonguarded\n" if $instance->{'nonguarded'}; - print OUT "log-output=FILE\n" if $instance->{'old_log_format'}; + if ( $mysql_version_id >= 50100 ) + { + print OUT "log-output=FILE\n" if $instance->{'old_log_format'}; + } print OUT "\n"; } From 693465a66ae47eaea24f39ec1f9e015b3b899736 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:15:04 +0200 Subject: [PATCH 051/235] Look for mysqlslap from 5.1, it's also available on windows --- mysql-test/mysql-test-run.pl | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index a2a840208da..b5fdf01ada4 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1307,6 +1307,10 @@ sub executable_setup () { $exe_mysqlbinlog= mtr_exe_exists("$path_client_bindir/mysqlbinlog"); $exe_mysqladmin= mtr_exe_exists("$path_client_bindir/mysqladmin"); $exe_mysql= mtr_exe_exists("$path_client_bindir/mysql"); + if ( $mysql_version_id >= 50100 ) + { + $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap"); + } # Look for mysql_fix_system_table script $exe_mysql_fix_system_tables= @@ -1540,21 +1544,18 @@ sub environment_setup () { # ---------------------------------------------------- # Setup env so childs can execute mysqlslap # ---------------------------------------------------- - unless ( $glob_win32 ) - { - my $cmdline_mysqlslap= - "$exe_mysqlslap -uroot " . - "--port=$master->[0]->{'port'} " . - "--socket=$master->[0]->{'path_sock'} --password= " . - "--lock-directory=$opt_tmpdir"; + my $cmdline_mysqlslap= + "$exe_mysqlslap -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password= " . + "--lock-directory=$opt_tmpdir"; - if ( $opt_debug ) - { - $cmdline_mysqlslap .= - " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; - } - $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap; + if ( $opt_debug ) + { + $cmdline_mysqlslap .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; } + $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap; # ---------------------------------------------------- # Setup env so childs can execute mysqlimport From 395a16482d16e7b54d7b2f55fe8dc286186a51c0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:19:06 +0200 Subject: [PATCH 052/235] Only setup cmdline_myslslap if exe_mysqlslap defined --- mysql-test/mysql-test-run.pl | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index b5fdf01ada4..7f2b61efb4c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1544,18 +1544,21 @@ sub environment_setup () { # ---------------------------------------------------- # Setup env so childs can execute mysqlslap # ---------------------------------------------------- - my $cmdline_mysqlslap= - "$exe_mysqlslap -uroot " . - "--port=$master->[0]->{'port'} " . - "--socket=$master->[0]->{'path_sock'} --password= " . - "--lock-directory=$opt_tmpdir"; - - if ( $opt_debug ) + if ( $exe_mysqlslap ) { - $cmdline_mysqlslap .= - " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; + my $cmdline_mysqlslap= + "$exe_mysqlslap -uroot " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'} --password= " . + "--lock-directory=$opt_tmpdir"; + + if ( $opt_debug ) + { + $cmdline_mysqlslap .= + " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; + } + $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap; } - $ENV{'MYSQL_SLAP'}= $cmdline_mysqlslap; # ---------------------------------------------------- # Setup env so childs can execute mysqlimport From 93c0cddbd4bb2767b9c93f2d90a419d61b37a81e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:34:05 +0200 Subject: [PATCH 053/235] Update "get_errcode_from_name" - add missing DBUG_RETURN - Change type of st_error->code to uint, that should be more than enough to hold the error numbers between 1000 and around 2000 --- client/mysqltest.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index d49693fa324..f4fa95afeb1 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2429,7 +2429,7 @@ void do_set_charset(struct st_command *command) typedef struct { const char *name; - long code; + uint code; } st_error; static st_error global_error_names[] = @@ -2443,8 +2443,8 @@ static st_error global_error_names[] = uint get_errcode_from_name(char *error_name, char *error_end) { -#ifdef HAVE_MYSQLD_ERNAME DBUG_ENTER("get_errcode_from_name"); +#ifdef HAVE_MYSQLD_ERNAME /* SQL error as string */ st_error *e= global_error_names; @@ -2461,8 +2461,7 @@ uint get_errcode_from_name(char *error_name, char *error_end) if (!strncmp(error_name, e->name, (int) (error_end - error_name)) && (uint) strlen(e->name) == (uint) (error_end - error_name)) { - return (uint) e->code; - break; + DBUG_RETURN(e->code); } } if (!e->name) @@ -2472,7 +2471,7 @@ uint get_errcode_from_name(char *error_name, char *error_end) LINT_INIT(error_end); abort_not_in_this_version(); #endif - return 0; + DBUG_RETURN(0);; } From 70c1311fb9431cddd087dbb046746ff133f64699 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:48:24 +0200 Subject: [PATCH 054/235] Update test results to new mysqltest Remove extra space for "send" commands mysql-test/extra/rpl_tests/rpl_truncate_helper.test: Get $SERVER_VERSION from the mysqld mysql-test/r/flush_table.result: Remove extra space for "send" commands mysql-test/r/handler_innodb.result: Remove extra space for "send" commands mysql-test/r/lock_multi.result: Remove extra space for "send" commands mysql-test/r/log_tables.result: Remove extra space for "send" commands --- .../extra/rpl_tests/rpl_truncate_helper.test | 1 + mysql-test/r/flush_table.result | 6 ++--- mysql-test/r/handler_innodb.result | 4 ++-- mysql-test/r/lock_multi.result | 24 +++++++++---------- mysql-test/r/log_tables.result | 4 ++-- 5 files changed, 20 insertions(+), 19 deletions(-) diff --git a/mysql-test/extra/rpl_tests/rpl_truncate_helper.test b/mysql-test/extra/rpl_tests/rpl_truncate_helper.test index 1e485baca36..7f1506c4010 100644 --- a/mysql-test/extra/rpl_tests/rpl_truncate_helper.test +++ b/mysql-test/extra/rpl_tests/rpl_truncate_helper.test @@ -36,6 +36,7 @@ SELECT * FROM t1; --echo **** On Master **** connection master; DROP TABLE t1; +let $SERVER_VERSION=`select version()`; --replace_result $SERVER_VERSION SERVER_VERSION --replace_regex /\/\* xid=[0-9]+ \*\//\/* xid= *\// /table_id: [0-9]+/table_id: #/ SHOW BINLOG EVENTS; diff --git a/mysql-test/r/flush_table.result b/mysql-test/r/flush_table.result index b29c83eb574..8821bade6b4 100644 --- a/mysql-test/r/flush_table.result +++ b/mysql-test/r/flush_table.result @@ -9,7 +9,7 @@ test.t1 check status OK unlock tables; lock table t1 read; lock table t1 read; - flush table t1; +flush table t1; select * from t1; a 1 @@ -19,7 +19,7 @@ a 1 unlock tables; lock table t1 write; - lock table t1 read; +lock table t1 read; flush table t1; select * from t1; a @@ -27,7 +27,7 @@ a unlock tables; unlock tables; lock table t1 read; - lock table t1 write; +lock table t1 write; flush table t1; select * from t1; a diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result index 89569d918ca..1bd50612a3f 100644 --- a/mysql-test/r/handler_innodb.result +++ b/mysql-test/r/handler_innodb.result @@ -476,7 +476,7 @@ handler t1 read first; c1 1 send the below to another connection, do not wait for the result - optimize table t1; +optimize table t1; proceed with the normal connection handler t1 read next; c1 @@ -502,7 +502,7 @@ flush tables with read lock; drop table t1; ERROR HY000: Can't execute the query because you have a conflicting read lock send the below to another connection, do not wait for the result - drop table t1; +drop table t1; proceed with the normal connection select * from t1; c1 diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 8ff02d898a3..07b8bf78efd 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -2,8 +2,8 @@ drop table if exists t1,t2; create table t1(n int); insert into t1 values (1); lock tables t1 write; - update low_priority t1 set n = 4; - select n from t1; +update low_priority t1 set n = 4; +select n from t1; unlock tables; n 4 @@ -11,8 +11,8 @@ drop table t1; create table t1(n int); insert into t1 values (1); lock tables t1 read; - update low_priority t1 set n = 4; - select n from t1; +update low_priority t1 set n = 4; +select n from t1; unlock tables; n 1 @@ -23,7 +23,7 @@ insert into t1 values(1,1); insert into t1 values(2,2); insert into t2 values(1,2); lock table t1 read; - update t1,t2 set c=a where b=d; +update t1,t2 set c=a where b=d; select c from t2; c 2 @@ -32,7 +32,7 @@ drop table t2; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write; - insert t1 select * from t2; +insert t1 select * from t2; drop table t2; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; @@ -54,7 +54,7 @@ use mysql; LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE; FLUSH TABLES; use mysql; - SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; +SELECT user.Select_priv FROM user, db WHERE user.user = db.user LIMIT 1; OPTIMIZE TABLES columns_priv, db, host, user; Table Op Msg_type Msg_text mysql.columns_priv optimize status OK @@ -68,14 +68,14 @@ use test; use test; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; - FLUSH TABLES WITH READ LOCK; +FLUSH TABLES WITH READ LOCK; CREATE TABLE t2 (c1 int); UNLOCK TABLES; UNLOCK TABLES; DROP TABLE t1, t2; CREATE TABLE t1 (c1 int); LOCK TABLE t1 WRITE; - FLUSH TABLES WITH READ LOCK; +FLUSH TABLES WITH READ LOCK; CREATE TABLE t2 AS SELECT * FROM t1; ERROR HY000: Table 't2' was not locked with LOCK TABLES UNLOCK TABLES; @@ -83,7 +83,7 @@ UNLOCK TABLES; DROP TABLE t1; CREATE DATABASE mysqltest_1; FLUSH TABLES WITH READ LOCK; - DROP DATABASE mysqltest_1; +DROP DATABASE mysqltest_1; DROP DATABASE mysqltest_1; ERROR HY000: Can't execute the query because you have a conflicting read lock UNLOCK TABLES; @@ -91,7 +91,7 @@ DROP DATABASE mysqltest_1; ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; lock tables t1 write; - alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // - alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // +alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // +alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; alter table t1 auto_increment=0; // unlock tables; drop table t1; diff --git a/mysql-test/r/log_tables.result b/mysql-test/r/log_tables.result index 638c05dd712..53b2fd9f4d8 100644 --- a/mysql-test/r/log_tables.result +++ b/mysql-test/r/log_tables.result @@ -39,14 +39,14 @@ ERROR HY000: You can't use usual read lock with log tables. Try READ LOCAL inste lock tables mysql.slow_log READ LOCAL, mysql.general_log READ LOCAL; unlock tables; lock tables mysql.general_log READ LOCAL; - flush logs; +flush logs; unlock tables; select "Mark that we woke up from flush logs in the test" as "test passed"; test passed Mark that we woke up from flush logs in the test lock tables mysql.general_log READ LOCAL; - truncate mysql.general_log; +truncate mysql.general_log; unlock tables; select "Mark that we woke up from TRUNCATE in the test" as "test passed"; From bd1f1d9841805d1cb05ea5ebeec5d73520e6c140 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 4 Oct 2006 23:57:31 +0200 Subject: [PATCH 055/235] Add skip-bdb to im defaults file in 5.0 --- mysql-test/mysql-test-run.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7f2b61efb4c..dac1a4b553e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2541,7 +2541,10 @@ skip-innodb skip-ndbcluster EOF ; - + if ( $mysql_version_id < 50100 ) + { + print OUT "skip-bdb\n"; + } print OUT "nonguarded\n" if $instance->{'nonguarded'}; if ( $mysql_version_id >= 50100 ) { From 49859bd66dcb819456464a170a0ebba0c6cededb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 00:00:34 +0200 Subject: [PATCH 056/235] Update result file mysql-test/r/im_utils.result: Change order of ouput, skip-bdb is now after skip-ndbcluster --- mysql-test/r/im_utils.result | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result index f671089d31d..626f24b4635 100644 --- a/mysql-test/r/im_utils.result +++ b/mysql-test/r/im_utils.result @@ -22,8 +22,8 @@ basedir VALUE server_id VALUE skip-stack-trace VALUE skip-innodb VALUE -skip-bdb VALUE skip-ndbcluster VALUE +skip-bdb VALUE SHOW INSTANCE OPTIONS mysqld2; option_name value instance_name VALUE @@ -42,8 +42,8 @@ basedir VALUE server_id VALUE skip-stack-trace VALUE skip-innodb VALUE -skip-bdb VALUE skip-ndbcluster VALUE +skip-bdb VALUE START INSTANCE mysqld2; Success: the process has been started. STOP INSTANCE mysqld2; From 08ef106201b42fea50117325756833a19491bd24 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 00:12:54 +0200 Subject: [PATCH 057/235] Set the small configuration a little bit larger for 4.1 --- mysql-test/mysql-test-run.pl | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dac1a4b553e..f40077e53a1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1959,11 +1959,22 @@ sub ndbcluster_start_install ($) { if (!$opt_bench) { # Use a smaller configuration - $ndb_no_ord=32; - $ndb_con_op=5000; - $ndb_dmem="20M"; - $ndb_imem="1M"; - $ndb_pbmem="4M"; + if ( $mysql_version_id < 50000 ) + { + # 4.1 is using a "larger" --small configuration + $ndb_no_ord=128; + $ndb_con_op=10000; + $ndb_dmem="40M"; + $ndb_imem="12M"; + } + else + { + $ndb_no_ord=32; + $ndb_con_op=5000; + $ndb_dmem="20M"; + $ndb_imem="1M"; + $ndb_pbmem="4M"; + } } my $config_file_template= "ndb/ndb_config_${nodes}_node.ini"; From 95e329152f9d168aab504752dbd0c34517febb0b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 00:19:24 +0200 Subject: [PATCH 058/235] Fix detection of debug binaries. If mysqld ouputs "debug xx" in the variable list it's a debug binary --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f40077e53a1..1ff0b57687b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1889,7 +1889,7 @@ sub check_ssl_support ($) { sub check_debug_support ($) { my $mysqld_variables= shift; - if ( $mysqld_variables->{'debug'} ) + if ( ! $mysqld_variables->{'debug'} ) { #mtr_report("Binaries are not debug compiled"); $debug_compiled_binaries= 0; From ec061718af55d026496ade752dada3ff703c9453 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 00:36:03 +0200 Subject: [PATCH 059/235] Update result file Get server version from mysqld mysql-test/r/lock_multi.result: Update result format to latest version of mysqltest, remove leading scpace from query that has been "send" mysql-test/t/rpl_truncate_7ndb.test: get server version from mysqld --- mysql-test/r/lock_multi.result | 2 +- mysql-test/t/rpl_truncate_7ndb.test | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result index 07b8bf78efd..2445b3e0c69 100644 --- a/mysql-test/r/lock_multi.result +++ b/mysql-test/r/lock_multi.result @@ -39,7 +39,7 @@ drop table t1; create table t1 (a int); create table t2 (a int); lock table t1 write, t2 write, t1 as t1_2 write, t2 as t2_2 write; - insert t1 select * from t2; +insert t1 select * from t2; drop table t2; ERROR 42S02: Table 'test.t2' doesn't exist drop table t1; diff --git a/mysql-test/t/rpl_truncate_7ndb.test b/mysql-test/t/rpl_truncate_7ndb.test index b0d4bdfc763..1d69eee5dd0 100644 --- a/mysql-test/t/rpl_truncate_7ndb.test +++ b/mysql-test/t/rpl_truncate_7ndb.test @@ -39,6 +39,7 @@ SELECT * FROM t1 ORDER BY a,b; --echo **** On Master **** connection master; DROP TABLE t1; +let SERVER_VERSION=`select version()`; --replace_regex /\/\* xid=[0-9]+ \*\//\/* xid= *\// /table_id: [0-9]+/table_id: #/ --replace_result $SERVER_VERSION SERVER_VERSION SHOW BINLOG EVENTS; From 4c8931294b600b2388d970e2324c4fc63ccea4b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 12:25:24 +0200 Subject: [PATCH 060/235] Improve "check_eol_junk" to detect junk although there are multi line comments in the way. I.e take advantage of the fact that a # comment is always terminated by a new line Add tests for the above client/mysqltest.c: Improve "check_eol_junk" to detect junk although there are multi line comments in the way. I.e take advantage of the fact that a # comment is always terminated by a new line mysql-test/r/mysqltest.result: Update resut file mysql-test/t/mysqltest.test: Add test for improved check_eol_junk --- client/mysqltest.c | 44 +++++++++++++++++---- mysql-test/r/mysqltest.result | 17 ++++++++ mysql-test/t/mysqltest.test | 74 ++++++++++++++++++++++++++++++++--- 3 files changed, 121 insertions(+), 14 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index f4fa95afeb1..87d8484dbf8 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3578,17 +3578,15 @@ void scan_command_for_warnings(struct st_command *command) /* Check for unexpected "junk" after the end of query - This is normally caused by missing delimiters + This is normally caused by missing delimiters or when + switching between different delimiters */ -void check_eol_junk(const char *eol) +void check_eol_junk_line(const char *line) { - const char *p= eol; - DBUG_ENTER("check_eol_junk"); - DBUG_PRINT("enter", ("eol: %s", eol)); - /* Remove all spacing chars except new line */ - while (*p && my_isspace(charset_info, *p) && (*p != '\n')) - p++; + const char *p= line; + DBUG_ENTER("check_eol_junk_line"); + DBUG_PRINT("enter", ("line: %s", line)); /* Check for extra delimiter */ if (*p && !strncmp(p, delimiter, delimiter_length)) @@ -3604,6 +3602,36 @@ void check_eol_junk(const char *eol) DBUG_VOID_RETURN; } +void check_eol_junk(const char *eol) +{ + const char *p= eol; + DBUG_ENTER("check_eol_junk"); + DBUG_PRINT("enter", ("eol: %s", eol)); + + /* Skip past all spacing chars and comments */ + while (*p && (my_isspace(charset_info, *p) || *p == '#' || *p == '\n')) + { + /* Skip past comments started with # and ended with newline */ + if (*p && *p == '#') + { + p++; + while (*p && *p != '\n') + p++; + } + + /* Check this line */ + if (*p && *p == '\n') + check_eol_junk_line(p); + + if (*p) + p++; + } + + check_eol_junk_line(p); + + DBUG_VOID_RETURN; +} + /* diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 4c243a64484..ed7267fb71d 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -152,6 +152,23 @@ mysqltest: At line 1: Missing delimiter mysqltest: At line 1: End of line junk detected: "sleep 7 # Another comment " +mysqltest: At line 1: Missing delimiter +mysqltest: At line 1: Missing delimiter +mysqltest: At line 1: End of line junk detected: "disconnect default + +# +# comment +# comment2 + +# comment 3 +--disable_query_log +" +mysqltest: At line 1: End of line junk detected: "disconnect default # comment +# comment part2 + +# comment 3 +--disable_query_log +" mysqltest: At line 1: Extra delimiter ";" found mysqltest: At line 1: Extra delimiter ";" found mysqltest: At line 1: Missing argument(s) to 'error' diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 5b0df28981f..d98375ca746 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -359,18 +359,80 @@ select 3 from t1 ; # Missing delimiter # The comment will be "sucked into" the sleep command since # delimiter is missing until after "show status" ---system echo "sleep 4" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql ---system echo "# A comment" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql ---system echo "show status;" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +sleep 4 +# A comment +show status; +EOF --error 1 --exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 # # Missing delimiter until eof # The comment will be "sucked into" the sleep command since -# delimiter is missing ---system echo "sleep 7" > $MYSQLTEST_VARDIR/tmp/mysqltest.sql ---system echo "# Another comment" >> $MYSQLTEST_VARDIR/tmp/mysqltest.sql +# delimiter is missing +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +sleep 7 +# Another comment +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 + +# +# Missing delimiter until "disable_query_log" +# +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +disconnect default + +# +# comment +# comment 3 +disable_query_log; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 + +# +# Missing delimiter until "disable_query_log" +# +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +disconnect default + +# +# comment + +# comment 3 +disable_query_log; +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 + +# +# Missing delimiter until eof +# +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +disconnect default + +# +# comment +# comment2 + +# comment 3 +--disable_query_log +EOF +--error 1 +--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 + +# +# Missing delimiter until eof +# +--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql +disconnect default # comment +# comment part2 + +# comment 3 +--disable_query_log +EOF --error 1 --exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1 From c3e8fb57a068cf192b273d94ff6ff0f267a08ce0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 12:28:23 +0200 Subject: [PATCH 061/235] Set the environment variable NDB_STATUS_OK to indicate that cluster is installed ok. This is actually not needed for this script as it will skip ndb tests if cluster install failed. But provided for compatibility mysql-test/include/have_ndb.inc: Revert --- mysql-test/include/have_ndb.inc | 1 + mysql-test/mysql-test-run.pl | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/mysql-test/include/have_ndb.inc b/mysql-test/include/have_ndb.inc index 84e60657876..9b85197abe8 100644 --- a/mysql-test/include/have_ndb.inc +++ b/mysql-test/include/have_ndb.inc @@ -1,3 +1,4 @@ +--exec test x$NDB_STATUS_OK = x1 -- require r/have_ndb.require disable_query_log; show variables like "have_ndbcluster"; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1ff0b57687b..d74a4e6c3be 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2665,6 +2665,19 @@ sub do_before_run_mysqltest($) { mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); } + + if ( $mysql_version_id < 50000 ) + { + # Set envirnoment variable NDB_STATUS_OK to 1 + # if script decided to run mysqltest cluster _is_ installed ok + $ENV{'NDB_STATUS_OK'} = "1"; + } + elsif ( $mysql_version_id < 50100 ) + { + # Set envirnoment variable NDB_STATUS_OK to YES + # if script decided to run mysqltest cluster _is_ installed ok + $ENV{'NDB_STATUS_OK'} = "YES"; + } } sub do_after_run_mysqltest($) From a4b13f10f55b64e4b61d9ea19c950c98f33f6cfb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 12:41:26 +0200 Subject: [PATCH 062/235] Add missing semicolon --- mysql-test/t/wait_timeout.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/wait_timeout.test b/mysql-test/t/wait_timeout.test index 195d1a5d3f2..67ed8fedfeb 100644 --- a/mysql-test/t/wait_timeout.test +++ b/mysql-test/t/wait_timeout.test @@ -52,7 +52,7 @@ select 2; select 3; # Disconnect so that we will not be confused by a future abort from this # connection. -disconnect default +disconnect default; # # Do the same test as above on a TCP connection From ddf0fa97b54f0cfd167af933c9169a1a5acfcabc Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 13:09:06 +0200 Subject: [PATCH 063/235] Print warning message if test was failed becuase of cluster install failure Improve check of wheter test case need slave cluster --- mysql-test/mysql-test-run.pl | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index d74a4e6c3be..f680ed909b2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2619,21 +2619,24 @@ sub run_testcase_check_skip_test($) return 1; } - # If test needs cluster, check that master installed ok - if ( $tinfo->{'ndb_test'} and !$clusters->[0]->{'installed_ok'} ) + if ($tinfo->{'ndb_test'}) { - mtr_report_test_name($tinfo); - mtr_report_test_failed($tinfo); - return 1; - } + foreach my $cluster (@{$clusters}) + { + last if ($opt_skip_ndbcluster_slave and + $cluster->{'name'} eq 'Slave'); - # If test needs slave cluster, check that it installed ok - if ( $tinfo->{'ndb_test'} and $tinfo->{'slave_num'} and - !$clusters->[1]->{'installed_ok'} ) - { - mtr_report_test_name($tinfo); - mtr_report_test_failed($tinfo); - return 1; + # If test needs this cluster, check it was installed ok + if ( !$cluster->{'installed_ok'} ) + { + mtr_tofile($path_timefile, + "Test marked as failed because $cluster->{'name'} " . + "was not installed ok!"); + mtr_report_test_name($tinfo); + mtr_report_test_failed($tinfo); + return 1; + } + } } return 0; From 9674059f685dc3421f3ce68d41b19d7572f61196 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 13:38:08 +0200 Subject: [PATCH 064/235] Add regex to detect the empty line that end the variable list. Some variable names in 5.1 is soo long that there is no space inbetween name and value. Outputing a warning about it, as that should probably be fixed. At least one space should be put between the name and value. --- mysql-test/mysql-test-run.pl | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f680ed909b2..5ae5684d14c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1189,9 +1189,19 @@ sub check_mysqld_features () { } else { - # The variable list is ended with a blank line, so when a line - # doesn't match the above regex, break the loop - last; + # The variable list is ended with a blank line + if ( $line =~ /^[\s]*$/ ) + { + last; + } + else + { + # Send out a warning, we should fix the variables that has no + # space between variable name and it's value + # or should it be fixed width column parsing? It does not + # look like that in function my_print_variables in my_getopt.c + mtr_warning("Could not parse variable list line : $line"); + } } } } From 2317c0cf59414a682babe1d434d1fd32cfc37f82 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 13:45:50 +0200 Subject: [PATCH 065/235] 5.0 is also using the somewhat larger config for cluster --- mysql-test/mysql-test-run.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5ae5684d14c..04daeb11b02 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1969,9 +1969,9 @@ sub ndbcluster_start_install ($) { if (!$opt_bench) { # Use a smaller configuration - if ( $mysql_version_id < 50000 ) + if ( $mysql_version_id < 50100 ) { - # 4.1 is using a "larger" --small configuration + # 4.1 and 5.0 is using a "larger" --small configuration $ndb_no_ord=128; $ndb_con_op=10000; $ndb_dmem="40M"; From 068641aa53ccbb0aa3654ba2171ae6785d46a4ad Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 14:37:46 +0200 Subject: [PATCH 066/235] Add new option --mem to mysql-test-run.pl. It will automatically setup a symlink from var/ to a tmpfs area and thereby speed up the execution of the testsuite significantly mysql-test/mysql-test-run.pl: Add new option --mem to mysql-test-run.pl. It will automatically setup a symlink from var/ to a tmpfs area and thereby speed up the execution of the testsuite significantly --- mysql-test/mysql-test-run.pl | 71 ++++++++++++++++++++++++++++++++---- 1 file changed, 63 insertions(+), 8 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 04daeb11b02..20123a68159 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -209,6 +209,7 @@ our $opt_fast; our $opt_force; our $opt_reorder= 0; our $opt_enable_disabled; +our $opt_mem; our $opt_gcov; our $opt_gcov_err; @@ -643,6 +644,7 @@ sub command_line_setup () { 'tmpdir=s' => \$opt_tmpdir, 'vardir=s' => \$opt_vardir, 'benchdir=s' => \$glob_mysql_bench_dir, + 'mem' => \$opt_mem, # Misc 'comment=s' => \$opt_comment, @@ -715,6 +717,32 @@ sub command_line_setup () { } mtr_report("Using binlog format '$used_binlog_format'"); + # -------------------------------------------------------------------------- + # Check if we should speed up tests by trying to run on tmpfs + # -------------------------------------------------------------------------- + if ( $opt_mem ) + { + mtr_error("Can't use --mem and --vardir at the same time ") + if $opt_vardir; + mtr_error("Can't use --mem and --tmpdir at the same time ") + if $opt_tmpdir; + + # Use /dev/shm as the preferred location for vardir and + # thus implicitly also tmpdir. Add other locations to list + my @tmpfs_locations= ("/dev/shm"); + # One could maybe use "mount" to find tmpfs location(s) + foreach my $fs (@tmpfs_locations) + { + if ( -d $fs ) + { + mtr_report("Using tmpfs in $fs"); + $opt_mem= "$fs/var"; + $opt_mem .= $ENV{'MTR_BUILD_THREAD'} if $ENV{'MTR_BUILD_THREAD'}; + last; + } + } + } + # -------------------------------------------------------------------------- # Set the "var/" directory, as it is the base for everything else # -------------------------------------------------------------------------- @@ -1771,6 +1799,8 @@ sub kill_running_server () { sub cleanup_stale_files () { + my $created_by_mem_file= "$glob_mysql_test_dir/var/created_by_mem"; + mtr_report("Removing Stale Files"); if ( $opt_vardir eq "$glob_mysql_test_dir/var" ) @@ -1778,15 +1808,26 @@ sub cleanup_stale_files () { # # Running with "var" in mysql-test dir # - if ( -l "$glob_mysql_test_dir/var" ) + if ( -l $opt_vardir) { - # Some users creates a soft link in mysql-test/var to another area - # - allow it - mtr_report("WARNING: Using the 'mysql-test/var' symlink"); - rmtree("$opt_vardir/log"); - rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port"); - rmtree("$opt_vardir/run"); - rmtree("$opt_vardir/tmp"); + # var is a symlink + if (-f $created_by_mem_file) + { + # Remove the directory which the link points at + rmtree(readlink($opt_vardir)); + # Remove the entire "var" dir + rmtree("$opt_vardir/"); + } + else + { + # Some users creates a soft link in mysql-test/var to another area + # - allow it + mtr_report("WARNING: Using the 'mysql-test/var' symlink"); + rmtree("$opt_vardir/log"); + rmtree("$opt_vardir/ndbcluster-$opt_ndbcluster_port"); + rmtree("$opt_vardir/run"); + rmtree("$opt_vardir/tmp"); + } } else { @@ -1808,6 +1849,17 @@ sub cleanup_stale_files () { rmtree("$opt_vardir/"); } + if ( $opt_mem ) + { + # Runinng with var as a link to some "memory" location, normally tmpfs + rmtree($opt_mem); + mkpath($opt_mem); + mtr_verbose("Creating symlink from $opt_vardir to $opt_mem"); + symlink($opt_mem, $opt_vardir); + # Put a small file to recognize this dir was created by --mem + mtr_tofile($created_by_mem_file, $opt_mem); + } + mkpath("$opt_vardir/log"); mkpath("$opt_vardir/run"); mkpath("$opt_vardir/tmp"); @@ -4326,6 +4378,9 @@ Options to control directories to use vardir=DIR The directory where files generated from the test run is stored (default: ./var). Specifying a ramdisk or tmpfs will speed up tests. + mem=DIR Run testsuite in "memory" using tmpfs if + available(default: /dev/shm) + Options to control what test suites or cases to run From 8a27de8371fd9762bb2cb40677093debce6d834b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 14:38:57 +0200 Subject: [PATCH 067/235] Update result file, --skip-bdb is not passed to mysqld's started by im in 5.1 --- mysql-test/r/im_utils.result | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result index 4a07faf4331..6e40c9bb1c0 100644 --- a/mysql-test/r/im_utils.result +++ b/mysql-test/r/im_utils.result @@ -22,7 +22,6 @@ server_id VALUE skip-stack-trace VALUE skip-innodb VALUE skip-ndbcluster VALUE -skip-bdb VALUE log-output VALUE SHOW INSTANCE OPTIONS mysqld2; option_name value @@ -41,7 +40,6 @@ server_id VALUE skip-stack-trace VALUE skip-innodb VALUE skip-ndbcluster VALUE -skip-bdb VALUE nonguarded VALUE log-output VALUE START INSTANCE mysqld2; From 6d89bcbcff64c09ad280a43b6c9106cef7868af0 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 18:00:20 +0200 Subject: [PATCH 068/235] Bug #20010 mysql-test-run.pl: --record and --require conflict (test fails) - When --record is passed to mysqltest the whole testcase should be executed as it normally is while the output form the test is acumulating in ds_res. When test has finished ds_res should simply be written to the specified result file(if any) instead of comapring it against the result file. Simplify handling of --require and also the cecking of result files by splitting check_result function into one function 'check_require' that is specialised in checking require's and leave 'check_result' to do just that. - "mysqltest --record" has been considered unsafe, but with this really simple logic, it should be safe to use. client/mysqltest.c: When --record is passed to mysqltest the whole testcase should be executed as it normally is while the output form the test is acumulating in ds_res. When test has finished ds_res should simply be written to the specified result file(if any) instead of comapring it against the result file. Simplify handling of --require and also the cecking of result files by splitting check_result function into one function 'check_require' that is specialised in checking require's and leave 'check_result' to do just that. --- client/mysqltest.c | 181 ++++++++++++++++++++++++--------------------- 1 file changed, 95 insertions(+), 86 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 87d8484dbf8..96bb5d6b80b 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -192,7 +192,7 @@ struct } master_pos; /* if set, all results are concated and compared against this file */ -const char *result_file= 0; +const char *result_file_name= 0; typedef struct st_var { @@ -382,9 +382,9 @@ struct st_command { char *query, *query_buf,*first_argument,*last_argument,*end; int first_word_len, query_len; - my_bool abort_on_error, require_file; + my_bool abort_on_error; struct st_expected_errors expected_errors; - char record_file[FN_REFLEN]; + char require_file[FN_REFLEN]; enum enum_commands type; }; @@ -410,9 +410,10 @@ VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing); void eval_expr(VAR* v, const char *p, const char** p_end); my_bool match_delimiter(int c, const char *delim, uint length); -void dump_result_to_reject_file(const char *record_file, char *buf, int size); -void dump_result_to_log_file(const char *record_file, char *buf, int size); -void dump_warning_messages(const char *record_file); +void dump_result_to_reject_file(char *buf, int size); +void dump_result_to_log_file(char *buf, int size); +void dump_warning_messages(); +void dump_progress(); void do_eval(DYNAMIC_STRING *query_eval, const char *query, const char *query_end, my_bool pass_through_escape_chars); @@ -742,12 +743,12 @@ void die(const char *fmt, ...) va_end(args); /* Dump the result that has been accumulated so far to .log file */ - if (result_file && ds_res.length) - dump_result_to_log_file(result_file, ds_res.str, ds_res.length); + if (result_file_name && ds_res.length) + dump_result_to_log_file(ds_res.str, ds_res.length); /* Dump warning messages */ - if (result_file && ds_warning_messages.length) - dump_warning_messages(result_file); + if (result_file_name && ds_warning_messages.length) + dump_warning_messages(); /* Clean up and exit */ free_used_memory(); @@ -926,41 +927,32 @@ err: /* - Check the content of ds against content of file fname + Check the content of ds against result file SYNOPSIS check_result ds - content to be checked - fname - name of file to check against - require_option - if set and check fails, the test will be aborted - with the special exit code "not supported test" RETURN VALUES error - the function will not return */ -void check_result(DYNAMIC_STRING* ds, const char *fname, - my_bool require_option) +void check_result(DYNAMIC_STRING* ds) { - int res= dyn_string_cmp(ds, fname); + DBUG_ASSERT(result_file_name); DBUG_ENTER("check_result"); - if (res && require_option) + switch (dyn_string_cmp(ds, result_file_name)) { - char reason[FN_REFLEN]; - fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR); - abort_not_supported_test("Test requires: '%s'", reason); - } - switch (res) { case RESULT_OK: break; /* ok */ case RESULT_LENGTH_MISMATCH: - dump_result_to_reject_file(fname, ds->str, ds->length); + dump_result_to_reject_file(ds->str, ds->length); die("Result length mismatch"); break; case RESULT_CONTENT_MISMATCH: - dump_result_to_reject_file(fname, ds->str, ds->length); + dump_result_to_reject_file(ds->str, ds->length); die("Result content mismatch"); break; default: /* impossible */ @@ -971,6 +963,35 @@ void check_result(DYNAMIC_STRING* ds, const char *fname, } +/* + Check the content of ds against a require file + If match fails, abort the test with special error code + indicating that test is not supported + + SYNOPSIS + check_result + ds - content to be checked + fname - name of file to check against + + RETURN VALUES + error - the function will not return + +*/ + +void check_require(DYNAMIC_STRING* ds, const char *fname) +{ + DBUG_ENTER("check_require"); + + if (dyn_string_cmp(ds, fname)) + { + char reason[FN_REFLEN]; + fn_format(reason, fname, "", "", MY_REPLACE_EXT | MY_REPLACE_DIR); + abort_not_supported_test("Test requires: '%s'", reason); + } + DBUG_VOID_RETURN; +} + + static byte *get_var_key(const byte* var, uint* len, my_bool __attribute__((unused)) t) { @@ -2389,7 +2410,8 @@ int do_sleep(struct st_command *command, my_bool real_sleep) } -void do_get_file_name(char *filename, struct st_command *command) +void do_get_file_name(struct st_command *command, + char* dest, uint dest_max_len) { char *p= command->first_argument, *name; if (!*p) @@ -2400,7 +2422,7 @@ void do_get_file_name(char *filename, struct st_command *command) if (*p) *p++= 0; command->last_argument= p; - strmake(filename, name, FN_REFLEN); + strmake(dest, name, dest_max_len); } @@ -3672,8 +3694,7 @@ int read_command(struct st_command** command_ptr) insert_dynamic(&q_lines, (gptr) &command)) die(NullS); - command->record_file[0]= 0; - command->require_file= 0; + command->require_file[0]= 0; command->first_word_len= 0; command->query_len= 0; @@ -3767,8 +3788,8 @@ static struct my_option my_long_options[] = {"record", 'r', "Record output of test_file into result file.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"result-file", 'R', "Read/Store result from/in this file.", - (gptr*) &result_file, (gptr*) &result_file, 0, GET_STR, REQUIRED_ARG, - 0, 0, 0, 0, 0, 0}, + (gptr*) &result_file_name, (gptr*) &result_file_name, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"server-arg", 'A', "Send option value to embedded server as a parameter.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"server-file", 'F', "Read embedded server arguments from file.", @@ -4018,35 +4039,35 @@ void str_to_file(const char *fname, char *str, int size) } -void dump_result_to_reject_file(const char *record_file, char *buf, int size) +void dump_result_to_reject_file(char *buf, int size) { char reject_file[FN_REFLEN]; - str_to_file(fn_format(reject_file, record_file, "", ".reject", + str_to_file(fn_format(reject_file, result_file_name, "", ".reject", MY_REPLACE_EXT), buf, size); } -void dump_result_to_log_file(const char *record_file, char *buf, int size) +void dump_result_to_log_file(char *buf, int size) { char log_file[FN_REFLEN]; - str_to_file(fn_format(log_file, record_file, "", ".log", + str_to_file(fn_format(log_file, result_file_name, "", ".log", MY_REPLACE_EXT), buf, size); } -void dump_progress(const char *record_file) +void dump_progress(void) { char log_file[FN_REFLEN]; - str_to_file(fn_format(log_file, record_file, "", ".progress", + str_to_file(fn_format(log_file, result_file_name, "", ".progress", MY_REPLACE_EXT), ds_progress.str, ds_progress.length); } -void dump_warning_messages(const char *record_file) +void dump_warning_messages(void) { char warn_file[FN_REFLEN]; - str_to_file(fn_format(warn_file, record_file, "", ".warnings", + str_to_file(fn_format(warn_file, result_file_name, "", ".warnings", MY_REPLACE_EXT), ds_warning_messages.str, ds_warning_messages.length); } @@ -4608,7 +4629,7 @@ void handle_error(struct st_command *command, DBUG_ENTER("handle_error"); - if (command->require_file) + if (command->require_file[0]) { /* The query after a "--require" failed. This is fine as long the server @@ -5004,12 +5025,12 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags) } /* - When command->record_file is set the output of _this_ query + When command->require_file is set the output of _this_ query should be compared with an already existing file Create a temporary dynamic string to contain the output from this query. */ - if (command->record_file[0]) + if (command->require_file[0]) { init_dynamic_string(&ds_result, "", 1024, 1024); ds= &ds_result; @@ -5144,26 +5165,14 @@ void run_query(MYSQL *mysql, struct st_command *command, int flags) mysql_errno(mysql), mysql_error(mysql)); } - if (command->record_file[0]) + if (command->require_file[0]) { - /* A result file was specified for _this_ query */ - if (record) - { - /* - Recording in progress - Dump the output from _this_ query to the specified record_file - */ - str_to_file(command->record_file, ds->str, ds->length); - - } else { - - /* - The output from _this_ query should be checked against an already - existing file which has been specified using --require or --result - */ - check_result(ds, command->record_file, command->require_file); - } + /* A result file was specified for _this_ query + and the output should be checked against an already + existing file which has been specified using --require or --result + */ + check_require(ds, command->require_file); } dynstr_free(&ds_warnings); @@ -5391,7 +5400,7 @@ void mark_progress(struct st_command* command __attribute__((unused)), int main(int argc, char **argv) { struct st_command *command; - my_bool require_file= 0, q_send_flag= 0; + my_bool q_send_flag= 0; uint command_executed= 0, last_command_executed= 0; char save_file[FN_REFLEN]; MY_STAT res_info; @@ -5442,7 +5451,8 @@ int main(int argc, char **argv) init_dynamic_string(&ds_warning_messages, "", 0, 2048); parse_args(argc, argv); - DBUG_PRINT("info",("result_file: '%s'", result_file ? result_file : "")); + DBUG_PRINT("info",("result_file: '%s'", + result_file_name ? result_file_name : "")); if (mysql_server_init(embedded_server_arg_count, embedded_server_args, (char**) embedded_server_groups)) @@ -5594,9 +5604,8 @@ int main(int argc, char **argv) display_result_vertically= (command->type == Q_QUERY_VERTICAL); if (save_file[0]) { - strmov(command->record_file,save_file); - command->require_file=require_file; - save_file[0]=0; + strmake(command->require_file, save_file, sizeof(save_file)); + save_file[0]= 0; } run_query(&cur_con->mysql, command, QUERY_REAP_FLAG|QUERY_SEND_FLAG); display_result_vertically= old_display_result_vertically; @@ -5626,9 +5635,8 @@ int main(int argc, char **argv) if (save_file[0]) { - strmov(command->record_file,save_file); - command->require_file=require_file; - save_file[0]=0; + strmake(command->require_file, save_file, sizeof(save_file)); + save_file[0]= 0; } run_query(&cur_con->mysql, command, flags); command_executed++; @@ -5660,17 +5668,12 @@ int main(int argc, char **argv) command_executed++; command->last_argument= command->end; break; - case Q_RESULT: - do_get_file_name(save_file, command); - require_file=0; + case Q_REQUIRE: + do_get_file_name(command, save_file, sizeof(save_file)); break; case Q_ERROR: do_get_errcodes(command); break; - case Q_REQUIRE: - do_get_file_name(save_file, command); - require_file=1; - break; case Q_REPLACE: do_get_replace(command); break; @@ -5741,11 +5744,14 @@ int main(int argc, char **argv) else die("Parsing is already enabled"); break; - case Q_DIE: die("%s", command->first_argument); break; + case Q_RESULT: + die("result, deprecated command"); + break; + default: processed= 0; break; @@ -5802,12 +5808,14 @@ int main(int argc, char **argv) */ if (ds_res.length) { - if (result_file) + if (result_file_name) { + /* A result file has been specified */ + if (record) { - /* Dump the output from test to result file */ - str_to_file(result_file, ds_res.str, ds_res.length); + /* Recording - dump the output from test to result file */ + str_to_file(result_file_name, ds_res.str, ds_res.length); } else { @@ -5815,12 +5823,12 @@ int main(int argc, char **argv) - detect missing result file - detect zero size result file */ - check_result(&ds_res, result_file, 0); + check_result(&ds_res); } } else { - /* No result_file specified to compare with, print to stdout */ + /* No result_file_name specified to compare with, print to stdout */ printf("%s", ds_res.str); } } @@ -5829,7 +5837,8 @@ int main(int argc, char **argv) die("The test didn't produce any output"); } - if (!command_executed && result_file && my_stat(result_file, &res_info, 0)) + if (!command_executed && + result_file_name && my_stat(result_file_name, &res_info, 0)) { /* my_stat() successful on result file. Check if we have not run a @@ -5841,12 +5850,12 @@ int main(int argc, char **argv) die("No queries executed but result file found!"); } - if ( opt_mark_progress && result_file ) - dump_progress(result_file); + if ( opt_mark_progress && result_file_name ) + dump_progress(); /* Dump warning messages */ - if (result_file && ds_warning_messages.length) - dump_warning_messages(result_file); + if (result_file_name && ds_warning_messages.length) + dump_warning_messages(); dynstr_free(&ds_res); From 9ba3b3f2efe7e6e93810597f967f22f7b2d39019 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 18:29:59 +0200 Subject: [PATCH 069/235] Use same --slave-load-tmpdir in all versions(backport from 5.0) mysql-test/mysql-test-run.pl: Use same location for slave-load-tmpdir in all versions mysql-test/mysql-test-run.sh: Use same location for slave-load-tmpdir in all versions mysql-test/r/rpl_loaddata.result: Update result after changing slave-load-tmpdir to use a shorter path mysql-test/r/rpl_loaddatalocal.result: Update result after changing slave-load-tmpdir to use a shorter path mysql-test/r/rpl_log.result: Update result after changing slave-load-tmpdir to use a shorter path mysql-test/t/rpl_loaddatalocal.test: Use MYSQLTEST_VARDIR when specifying path to load from(backport from 5.0) Use new command "remove_file" instead of s"ystem rm" --- mysql-test/mysql-test-run.pl | 4 ---- mysql-test/mysql-test-run.sh | 2 +- mysql-test/r/rpl_loaddata.result | 2 +- mysql-test/r/rpl_loaddatalocal.result | 4 ++-- mysql-test/r/rpl_log.result | 12 ++++++------ mysql-test/t/rpl_loaddatalocal.test | 8 +++++--- 6 files changed, 15 insertions(+), 17 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 20123a68159..51989f02f0e 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3153,10 +3153,6 @@ sub mysqld_arguments ($$$$$) { # on the server. The path need to have constant length otherwise # test results will vary, thus a relative path is used. my $slave_load_path= "../tmp"; - if ( $mysql_version_id < 50000 ) - { - $slave_load_path= "../../var/tmp"; - } mtr_add_arg($args, "%s--slave-load-tmpdir=%s", $prefix, $slave_load_path); mtr_add_arg($args, "%s--socket=%s", $prefix, diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 15c7470a74c..141a725db2e 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -188,7 +188,7 @@ SYST=0 REALT=0 FAST_START="" MYSQL_TMP_DIR=$MYSQL_TEST_DIR/var/tmp -SLAVE_LOAD_TMPDIR=../../var/tmp #needs to be same length to test logging +SLAVE_LOAD_TMPDIR=../tmp #needs to be same length to test logging RES_SPACE=" " MYSQLD_SRC_DIRS="strings mysys include extra regex isam merge myisam \ myisammrg heap sql" diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index 65fc9d1b415..d0f2a885dcd 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -22,7 +22,7 @@ day id category name 2003-03-22 2416 a bbbbb show master status; File Position Binlog_Do_DB Binlog_Ignore_DB -slave-bin.000001 964 +slave-bin.000001 950 drop table t1; drop table t2; drop table t3; diff --git a/mysql-test/r/rpl_loaddatalocal.result b/mysql-test/r/rpl_loaddatalocal.result index b49ea842485..b2ca868a094 100644 --- a/mysql-test/r/rpl_loaddatalocal.result +++ b/mysql-test/r/rpl_loaddatalocal.result @@ -5,9 +5,9 @@ reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; create table t1(a int); -select * into outfile '../../var/master-data/rpl_loaddatalocal.select_outfile' from t1; +select * into outfile 'MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' from t1; truncate table t1; -load data local infile './var/master-data/rpl_loaddatalocal.select_outfile' into table t1; +load data local infile 'MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' into table t1; select a,count(*) from t1 group by a; a count(*) 1 10000 diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index 3833800bfeb..c496f3d540a 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -73,7 +73,7 @@ master-bin.000002 276 start slave; show binary logs; Log_name File_size -slave-bin.000001 1285 +slave-bin.000001 1278 slave-bin.000002 170 show binlog events in 'slave-bin.000001' from 4; Log_name Pos Event_type Server_id Orig_log_pos Info @@ -84,11 +84,11 @@ slave-bin.000001 200 Query 1 200 use `test`; insert into t1 values (NULL) slave-bin.000001 263 Query 1 263 use `test`; drop table t1 slave-bin.000001 311 Query 1 311 use `test`; create table t1 (word char(20) not null) slave-bin.000001 386 Create_file 1 386 db=test;table=t1;file_id=1;block_len=581 -slave-bin.000001 1065 Exec_load 1 1065 ;file_id=1 -slave-bin.000001 1088 Query 1 1088 use `test`; drop table t1 -slave-bin.000001 1136 Query 1 1136 use `test`; create table t5 (a int) -slave-bin.000001 1194 Query 1 1194 use `test`; drop table t5 -slave-bin.000001 1242 Rotate 2 1242 slave-bin.000002;pos=4 +slave-bin.000001 1058 Exec_load 1 1058 ;file_id=1 +slave-bin.000001 1081 Query 1 1081 use `test`; drop table t1 +slave-bin.000001 1129 Query 1 1129 use `test`; create table t5 (a int) +slave-bin.000001 1187 Query 1 1187 use `test`; drop table t5 +slave-bin.000001 1235 Rotate 2 1235 slave-bin.000002;pos=4 show binlog events in 'slave-bin.000002' from 4; Log_name Pos Event_type Server_id Orig_log_pos Info slave-bin.000002 4 Query 1 4 use `test`; create table t1 (n int) diff --git a/mysql-test/t/rpl_loaddatalocal.test b/mysql-test/t/rpl_loaddatalocal.test index 2ca142c3b64..fd91aba856a 100644 --- a/mysql-test/t/rpl_loaddatalocal.test +++ b/mysql-test/t/rpl_loaddatalocal.test @@ -20,11 +20,13 @@ while ($1) } set SQL_LOG_BIN=1; enable_query_log; -select * into outfile '../../var/master-data/rpl_loaddatalocal.select_outfile' from t1; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval select * into outfile '$MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' from t1; #This will generate a 20KB file, now test LOAD DATA LOCAL truncate table t1; -load data local infile './var/master-data/rpl_loaddatalocal.select_outfile' into table t1; -system rm ./var/master-data/rpl_loaddatalocal.select_outfile ; +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval load data local infile '$MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile' into table t1; +--remove_file $MYSQLTEST_VARDIR/master-data/rpl_loaddatalocal.select_outfile save_master_pos; connection slave; sync_with_master; From 2430d73ce68d0c64016f88f98431e0a67a19e97f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 20:21:11 +0200 Subject: [PATCH 070/235] Make use of $opt_mem" and let 4.1 allow --vardir to be set. Still relies on the var/ directory but having it on tmpfs gives a big speedup. mysql-test/mysql-test-run.pl: Make use of opt_mem and let 4.1 allow vardir to be set. Still relies on the var/ directory but having it on tmpfs gives a big speedup. --- mysql-test/mysql-test-run.pl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 51989f02f0e..7778b99ea65 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -754,7 +754,10 @@ sub command_line_setup () { elsif ( $mysql_version_id < 50000 ) { # --vardir was specified - mtr_error("--vardir option not supported until MySQL 5.0"); + # It's only supported in 4.1 as a symlink from var/ + # by setting up $opt_mem that will be created + $opt_mem= $opt_vardir; + $opt_vardir= undef; } $path_vardir_trace= $opt_vardir; From 16b9d8d15ab9f00b02b90bd3a5e50cb3d9543487 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 20:45:16 +0200 Subject: [PATCH 071/235] No need to pass --valgrind to mysqltest anymore, the simple task of creating an environment variable is handled directly from the perl code. --- mysql-test/mysql-test-run.pl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7778b99ea65..995baf2c0dd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1749,6 +1749,11 @@ sub environment_setup () { print "Using IM_MYSQLD2_PORT = $ENV{IM_MYSQLD2_PORT}\n"; } } + + # Create an environment variable to make it possible + # to detect that valgrind is being used from test cases + $ENV{'VALGRIND_TEST'}= $opt_valgrind; + } @@ -4009,11 +4014,6 @@ sub run_mysqltest ($) { mtr_add_arg($args, "--big-test"); } - if ( $opt_valgrind ) - { - mtr_add_arg($args, "--valgrind"); - } - if ( $opt_compress ) { mtr_add_arg($args, "--compress"); From 93a9883bed4acacf5d5cad9c04255047f1679ec6 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 22:05:42 +0200 Subject: [PATCH 072/235] Add policy directive about keeping mysqltest framework tools identical in all versions mysql-test/mysql-test-run.pl: Add policy directive about keeping mysqltest framework tools identical in all versions Cleanup the initial comment to reflect current state --- client/mysqltest.c | 2 ++ mysql-test/mysql-test-run.pl | 43 +++++++++++++----------------------- 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 96bb5d6b80b..cf3afced427 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -22,6 +22,8 @@ See the "MySQL Test framework manual" for more information http://dev.mysql.com/doc/mysqltest/en/index.html + Please keep the test framework tools identical in all versions! + Written by: Sasha Pachev Matt Wagner diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 995baf2c0dd..6c8befdafa6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1,30 +1,24 @@ #!/usr/bin/perl # -*- cperl -*- -# This is a transformation of the "mysql-test-run" Bourne shell script -# to Perl. There are reasons this rewrite is not the prettiest Perl -# you have seen # -# - The original script is huge and for most part uncommented, -# not even a usage description of the flags. +############################################################################## # -# - There has been an attempt to write a replacement in C for the -# original Bourne shell script. It was kind of working but lacked -# lot of functionality to really be a replacement. Not to redo -# that mistake and catch all the obscure features of the original -# script, the rewrite in Perl is more close to the original script -# meaning it also share some of the ugly parts as well. +# mysql-test-run.pl # -# - The original intention was that this script was to be a prototype -# to be the base for a new C version with full functionality. Since -# then it was decided that the Perl version should replace the -# Bourne shell version, but the Perl style still reflects the wish -# to make the Perl to C step easy. +# Tool used for executing a suite of .test file # -# Some coding style from the original intent has been kept +# See the "MySQL Test framework manual" for more information +# http://dev.mysql.com/doc/mysqltest/en/index.html +# +# Please keep the test framework tools identical in all versions! +# +############################################################################## +# +# Coding style directions for this perl script # # - To make this Perl script easy to alter even for those that not -# code Perl that often, the coding style is as close as possible to +# code Perl that often, keeep the coding style as close as possible to # the C/C++ MySQL coding standard. # # - All lists of arguments to send to commands are Perl lists/arrays, @@ -42,15 +36,6 @@ # the information. This separates the "find information" from the # "do the work" and makes the program more easy to maintain. # -# - At the moment, there are tons of "global" variables that control -# this script, even accessed from the files in "lib/*.pl". This -# will change over time, for now global variables are used instead -# of using %opt, %path and %exe hashes, because I want more -# compile time checking, that hashes would not give me. Once this -# script is debugged, hashes will be used and passed as parameters -# to functions, to more closely mimic how it would be coded in C -# using structs. -# # - The rule when it comes to the logic of this program is # # command_line_setup() - is to handle the logic between flags @@ -2758,10 +2743,12 @@ sub do_after_run_mysqltest($) my $tinfo= shift; my $tname= $tinfo->{'name'}; + mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n"); + # Save info from this testcase run to mysqltest.log mtr_appendfile_to_file($path_timefile, $path_mysqltest_log) if -f $path_timefile; - mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n"); + } From c3997a6640e4ff7933691d89b48e3268d45f6281 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 22:06:29 +0200 Subject: [PATCH 073/235] Open input file with "<" not ">>" --- mysql-test/lib/mtr_io.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl index 8a7fc56269c..a1d7ffe87d8 100644 --- a/mysql-test/lib/mtr_io.pl +++ b/mysql-test/lib/mtr_io.pl @@ -176,7 +176,7 @@ sub mtr_appendfile_to_file ($$) { my $to_file= shift; open(TOFILE,">>",$to_file) or mtr_error("can't open file \"$to_file\": $!"); - open(FROMFILE,">>",$from_file) + open(FROMFILE,"<",$from_file) or mtr_error("can't open file \"$from_file\": $!"); print TOFILE while (); close FROMFILE; From 7ec1a292a19e45270e87617ff0431f25d12e468d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 22:29:16 +0200 Subject: [PATCH 074/235] Print the newly found version number in human readable format --- mysql-test/mysql-test-run.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 6c8befdafa6..4162e8cf0ef 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1180,9 +1180,10 @@ sub check_mysqld_features () { # Look for version if ( $line =~ /^$exe_mysqld\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ ) { - print "Major: $1 Minor: $2 Build: $3\n"; + #print "Major: $1 Minor: $2 Build: $3\n"; $mysql_version_id= $1*10000 + $2*100 + $3; - print "mysql_version_id: $mysql_version_id\n"; + #print "mysql_version_id: $mysql_version_id\n"; + mtr_report("MySQL Version $1.$2.$3"); } } else From cae534e36f38dde5c34b320057a1df714d69cc5c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 5 Oct 2006 23:19:32 +0200 Subject: [PATCH 075/235] Add target to Makefile which uses the much faster --mem switch to mysql-test-run.pl --- Makefile.am | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Makefile.am b/Makefile.am index 2aefbd05283..8d0746e6a64 100644 --- a/Makefile.am +++ b/Makefile.am @@ -124,3 +124,8 @@ test-force-pl: cd mysql-test; \ ./mysql-test-run.pl --force && \ ./mysql-test-run.pl --ps-protocol --force + +test-force-pl-mem: + cd mysql-test; \ + ./mysql-test-run.pl --force --mem && \ + ./mysql-test-run.pl --ps-protocol --force --mem From d76252b4a6cb35734571b7ebce54b1e02b9f870d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 00:06:53 +0200 Subject: [PATCH 076/235] Update partition test to use the new command "file_exist" --- mysql-test/r/partition.result | 36 ++++--------------------- mysql-test/t/partition.test | 50 ++++++++++++++++++++++------------- 2 files changed, 37 insertions(+), 49 deletions(-) diff --git a/mysql-test/r/partition.result b/mysql-test/r/partition.result index d8d433ef216..3585971aaf4 100644 --- a/mysql-test/r/partition.result +++ b/mysql-test/r/partition.result @@ -1132,41 +1132,15 @@ drop table t1; create table t1 (a int) engine myisam partition by range (a) subpartition by hash (a) -(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx' +(partition p0 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx' (SUBPARTITION subpart00, SUBPARTITION subpart01)); -hello/master-data/test/t1.frm -hello/master-data/test/t1.par -hello/master-data/test/t1#P#p0#SP#subpart00.MYD -hello/master-data/test/t1#P#p0#SP#subpart00.MYI -hello/master-data/test/t1#P#p0#SP#subpart01.MYD -hello/master-data/test/t1#P#p0#SP#subpart01.MYI -hello/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD -hello/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD -hello/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI -hello/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI +Checking if file exists before alter ALTER TABLE t1 REORGANIZE PARTITION p0 INTO -(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx' +(partition p1 VALUES LESS THAN (1) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx' (SUBPARTITION subpart10, SUBPARTITION subpart11), -partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'hello/master-data/tmpdata' INDEX DIRECTORY = 'hello/master-data/tmpinx' +partition p2 VALUES LESS THAN (2) DATA DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpdata' INDEX DIRECTORY = 'MYSQLTEST_VARDIR/master-data/tmpinx' (SUBPARTITION subpart20, SUBPARTITION subpart21)); -hello/master-data/test/t1.frm -hello/master-data/test/t1.par -hello/master-data/test/t1#P#p1#SP#subpart10.MYD -hello/master-data/test/t1#P#p1#SP#subpart10.MYI -hello/master-data/test/t1#P#p1#SP#subpart11.MYD -hello/master-data/test/t1#P#p1#SP#subpart11.MYI -hello/master-data/test/t1#P#p2#SP#subpart20.MYD -hello/master-data/test/t1#P#p2#SP#subpart20.MYI -hello/master-data/test/t1#P#p2#SP#subpart21.MYD -hello/master-data/test/t1#P#p2#SP#subpart21.MYI -hello/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD -hello/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD -hello/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD -hello/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD -hello/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI -hello/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI -hello/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI -hello/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI +Checking if file exists after alter drop table t1; create table t1 (a bigint unsigned not null, primary key(a)) engine = myisam diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index 928d855f9f4..cae5c54849d 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1332,37 +1332,51 @@ eval SET @inx_dir = 'INDEX DIRECTORY = ''$MYSQLTEST_VARDIR/master-data/tmpinx''' let $inx_directory = `select @inx_dir`; --enable_query_log ---replace_result $MYSQLTEST_VARDIR "hello" +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval create table t1 (a int) engine myisam partition by range (a) subpartition by hash (a) (partition p0 VALUES LESS THAN (1) $data_directory $inx_directory (SUBPARTITION subpart00, SUBPARTITION subpart01)); ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/test/t1.* || true ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/test/t1#* || true ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/tmpdata/t1#* || true ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/tmpinx/t1#* || true ---replace_result $MYSQLTEST_VARDIR "hello" +--echo Checking if file exists before alter +--file_exist $MYSQLTEST_VARDIR/master-data/test/t1.frm +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart01.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart00.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p0#SP#subpart01.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart00.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p0#SP#subpart01.MYI +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval ALTER TABLE t1 REORGANIZE PARTITION p0 INTO (partition p1 VALUES LESS THAN (1) $data_directory $inx_directory (SUBPARTITION subpart10, SUBPARTITION subpart11), partition p2 VALUES LESS THAN (2) $data_directory $inx_directory (SUBPARTITION subpart20, SUBPARTITION subpart21)); ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/test/t1.* || true ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/test/t1#* || true ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/tmpdata/t1#* || true ---replace_result $MYSQLTEST_VARDIR "hello" ---exec ls $MYSQLTEST_VARDIR/master-data/tmpinx/t1#* || true +--echo Checking if file exists after alter +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.frm +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart10.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart10.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart11.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p1#SP#subpart11.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart20.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p2#SP#subpart21.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart10.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p1#SP#subpart11.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart20.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/tmpdata/t1#P#p2#SP#subpart21.MYD +--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart10.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p1#SP#subpart11.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart20.MYI +--file_exists $MYSQLTEST_VARDIR/master-data/tmpinx/t1#P#p2#SP#subpart21.MYI drop table t1; --exec rmdir $MYSQLTEST_VARDIR/master-data/tmpdata || true From 257cfa1ca01a2af8486a295c04b9a5cc4683a8ba Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 00:07:39 +0200 Subject: [PATCH 077/235] Turn on reconnect before crashing server --- mysql-test/t/crash_commit_before.test | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/crash_commit_before.test b/mysql-test/t/crash_commit_before.test index c46340d44dc..78444b7aa45 100644 --- a/mysql-test/t/crash_commit_before.test +++ b/mysql-test/t/crash_commit_before.test @@ -15,6 +15,9 @@ SET SESSION debug="d,crash_commit_before"; --error 2013 COMMIT; +# Turn on reconnect +--enable_reconnect + # Call script that will poll the server waiting for it to be back online again --source include/wait_until_connected_again.inc From 139b6917cb177fd40c529a2eb1ff1ef862dd3e22 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 00:11:25 +0200 Subject: [PATCH 078/235] partition test relies heavily on innodb, add "have_innodb" requirement --- mysql-test/t/partition.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index cae5c54849d..b9cd784ab93 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -4,6 +4,7 @@ # Taken fromm the select test # -- source include/have_partition.inc +-- source include/have_innodb.inc # # This test is disabled on Windows due to BUG#19107 # From fd141956768c7460e40af0b85f83f9e5d1f0803b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 00:36:25 +0200 Subject: [PATCH 079/235] Fix warning detected, file_exist => file_exists --- mysql-test/t/partition.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index b9cd784ab93..4cdf7a31915 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -1341,7 +1341,7 @@ subpartition by hash (a) (SUBPARTITION subpart00, SUBPARTITION subpart01)); --echo Checking if file exists before alter ---file_exist $MYSQLTEST_VARDIR/master-data/test/t1.frm +--file_exists $MYSQLTEST_VARDIR/master-data/test/t1.frm --file_exists $MYSQLTEST_VARDIR/master-data/test/t1.par --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYD --file_exists $MYSQLTEST_VARDIR/master-data/test/t1#P#p0#SP#subpart00.MYI From 78c5bc62c59b5b168fb0625a70cc465ead4e59ae Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 00:57:10 +0200 Subject: [PATCH 080/235] Add printout of file in which warning was detected Cleanup .progress, .reject, .log and .warnings files produced by mysqltest client/mysqltest.c: Add printout of file in which warning was detected mysql-test/include/ctype_like_escape.inc: Remove warnings, convert -- comments to # comments mysql-test/mysql-test-run.pl: Cleanup all files produced by mysqltest before starting mysqltest again --- client/mysqltest.c | 13 ++++++++++++- mysql-test/include/ctype_like_escape.inc | 4 ++-- mysql-test/mysql-test-run.pl | 15 ++++++++------- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index cf3afced427..8d8c20c3e8f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -818,6 +818,9 @@ void verbose_msg(const char *fmt, ...) va_start(args, fmt); fprintf(stderr, "mysqltest: "); + if (cur_file && cur_file != file_stack) + fprintf(stderr, "In included file \"%s\": ", + cur_file->file_name); if (start_lineno != 0) fprintf(stderr, "At line %u: ", start_lineno); vfprintf(stderr, fmt, args); @@ -839,7 +842,15 @@ void warning_msg(const char *fmt, ...) dynstr_append(&ds_warning_messages, "mysqltest: "); if (start_lineno != 0) { - len= my_snprintf(buff, sizeof(buff), "Warning detected at line %d: ", + dynstr_append(&ds_warning_messages, "Warning detected "); + if (cur_file && cur_file != file_stack) + { + len= my_snprintf(buff, sizeof(buff), "in included file %s ", + cur_file->file_name); + dynstr_append_mem(&ds_warning_messages, + buff, len); + } + len= my_snprintf(buff, sizeof(buff), "at line %d: ", start_lineno); dynstr_append_mem(&ds_warning_messages, buff, len); diff --git a/mysql-test/include/ctype_like_escape.inc b/mysql-test/include/ctype_like_escape.inc index ac97fbaa1a0..d4abc33c178 100644 --- a/mysql-test/include/ctype_like_escape.inc +++ b/mysql-test/include/ctype_like_escape.inc @@ -11,8 +11,8 @@ insert into t1 values('ab_def'); insert into t1 values('abc_ef'); insert into t1 values('abcd_f'); insert into t1 values('abcde_'); --- should return ab_def +# should return ab_def select c1 as c1u from t1 where c1 like 'ab\_def'; --- should return ab_def +# should return ab_def select c1 as c2h from t1 where c1 like 'ab#_def' escape '#'; drop table t1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4162e8cf0ef..23a9b30d76b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2704,15 +2704,16 @@ sub do_before_run_mysqltest($) my $tinfo= shift; my $tname= $tinfo->{'name'}; - # Remove old reject file - if ( $opt_suite eq "main" ) + # Remove old files produced by mysqltest + my $result_dir= "r"; + if ( ! $opt_suite eq "main" ) { - unlink("r/$tname.reject"); - } - else - { - unlink("suite/$opt_suite/r/$tname.reject"); + $result_dir= "suite/$opt_suite/r"; } + unlink("$result_dir/$tname.reject"); + unlink("$result_dir/$tname.progress"); + unlink("$result_dir/$tname.log"); + unlink("$result_dir/$tname.warnings"); mtr_tonewfile($path_current_test_log,"$tname\n"); # Always tell where we are From 1822065d1212762adbe00eae14e8e1cb6f4d736d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 01:22:33 +0200 Subject: [PATCH 081/235] Rename "snapshot_setup" to "datadir_setup" as that is what is done by it. Move call f dunction into "initialize_servers" so it's called also in stress and bench mode --- mysql-test/mysql-test-run.pl | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 23a9b30d76b..21f64bc3cb6 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -323,7 +323,7 @@ our $default_mysqld_port; sub main (); sub initial_setup (); sub command_line_setup (); -sub snapshot_setup (); +sub datadir_setup (); sub executable_setup (); sub environment_setup (); sub kill_running_server (); @@ -416,7 +416,6 @@ sub main () { unless $need_ndbcluster; $opt_skip_im= 1 unless $need_im; - snapshot_setup(); initialize_servers(); run_suite($opt_suite, $tests); @@ -1122,7 +1121,7 @@ sub command_line_setup () { $path_snapshot= "$opt_tmpdir/snapshot_$opt_master_myport/"; } -sub snapshot_setup () { +sub datadir_setup () { # Make a list of all data_dirs @data_dir_lst = ( @@ -2370,6 +2369,9 @@ sub run_suite () { ############################################################################## sub initialize_servers () { + + datadir_setup(); + if ( ! $glob_use_running_server ) { kill_running_server(); From 9350dbc4f96c0b58784132e1c0556e0238c53177 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 11:23:19 +0200 Subject: [PATCH 082/235] Improve 'run_testcase_need_master_restart' to require restart if master is not already started Improve 'run_testcase_need_slave_restart' to detect if a slave restart really is necessary. So far all rpl test requires a slave restart, but for all other tests it can be skipped Improve the sort order used by --reorder mysql-test/lib/mtr_cases.pl: Improve the sort order used by reorder mysql-test/mysql-test-run.pl: Improve 'run_testcase_need_master_restart' to require restart if master is not already started Improve 'run_testcase_need_slave_restart' to detect if a slave restart really is necessary. So far all rpl test requires a slave restart, but for all other tests it can be skipped --- mysql-test/lib/mtr_cases.pl | 31 ++++++++------ mysql-test/mysql-test-run.pl | 83 ++++++++++++++---------------------- 2 files changed, 51 insertions(+), 63 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index bb92730444c..344c80ac0bf 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -164,31 +164,36 @@ sub collect_test_cases ($) { # Make a mapping of test name to a string that represents how that test # should be sorted among the other tests. Put the most important criterion # first, then a sub-criterion, then sub-sub-criterion, et c. - foreach $tinfo (@$cases) + foreach $tinfo (@$cases) { my @this_criteria = (); + # # Append the criteria for sorting, in order of importance. - push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); # Ending with "~" makes empty sort later than filled + # + push(@this_criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); push(@this_criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); - push(@this_criteria, "big_test=" . ($tinfo->{'big_test'} ? "1" : "0")); - push(@this_criteria, join("|", sort keys %{$tinfo})); # Group similar things together. The values may differ substantially. FIXME? - push(@this_criteria, $tinfo->{'name'}); # Finally, order by the name - + # Group test with similar options together. + # Ending with "~" makes empty sort later than filled + push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); + + # Finally, order by the name + push(@this_criteria, $tinfo->{'name'}); + $sort_criteria{$tinfo->{"name"}} = join(" ", @this_criteria); } @$cases = sort { $sort_criteria{$a->{"name"}} cmp $sort_criteria{$b->{"name"}}; } @$cases; ### For debugging the sort-order -# foreach $tinfo (@$cases) -# { -# print $sort_criteria{$tinfo->{"name"}}; -# print " -> \t"; -# print $tinfo->{"name"}; -# print "\n"; -# } + foreach $tinfo (@$cases) + { + print $sort_criteria{$tinfo->{"name"}}; + print " -> \t"; + print $tinfo->{"name"}; + print "\n"; + } } return $cases; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 21f64bc3cb6..31a2c1e32a3 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3522,6 +3522,11 @@ sub run_testcase_need_master_restart($) join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); } + elsif( ! $master->[0]->{'pid'} ) + { + $do_restart= 1; + mtr_verbose("Restart because: master is not started"); + } return $do_restart; } @@ -3533,57 +3538,35 @@ sub run_testcase_need_slave_restart($) # We try to find out if we are to restart the slaves my $do_slave_restart= 0; # Assumes we don't have to - # FIXME only restart slave when necessary - $do_slave_restart= 1; + if ( $max_slave_num == 0) + { + mtr_verbose("No testcase use slaves, no slave restarts"); + } + else + { -# if ( ! $slave->[0]->{'pid'} ) -# { -# # mtr_verbose("Slave not started, no need to check slave restart"); -# } -# elsif ( $do_restart ) -# { -# $do_slave_restart= 1; # Always restart if master restart -# mtr_verbose("Restart slave because: Master restart"); -# } -# elsif ( $tinfo->{'slave_sh'} ) -# { -# $do_slave_restart= 1; # Always restart if script to run -# mtr_verbose("Restart slave because: Always restart if script to run"); -# } -# elsif ( ! $opt_skip_ndbcluster_slave and -# $tinfo->{'ndb_test'} == 0 and -# $clusters->[1]->{'pid'} != 0 ) -# { -# $do_slave_restart= 1; # Restart without slave cluster -# mtr_verbose("Restart slave because: Test does not need slave cluster"); -# } -# elsif ( ! $opt_with_ndbcluster_slave and -# $tinfo->{'ndb_test'} == 1 and -# $clusters->[1]->{'pid'} == 0 ) -# { -# $do_slave_restart= 1; # Restart with slave cluster -# mtr_verbose("Restart slave because: Test need slave cluster"); -# } -# elsif ( $tinfo->{'slave_restart'} ) -# { -# $do_slave_restart= 1; -# mtr_verbose("Restart slave because: slave_restart"); -# } -# elsif ( $slave->[0]->{'running_slave_is_special'} ) -# { -# $do_slave_restart= 1; -# mtr_verbose("Restart slave because: running_slave_is_special"); -# } -# # Check that running slave was started with same options -# # as the current test requires -# elsif (! mtr_same_opts($slave->[0]->{'start_opts'}, -# $tinfo->{'slave_opt'}) ) -# { -# $do_slave_restart= 1; -# mtr_verbose("Restart slave because: running with different options '" . -# join(" ", @{$tinfo->{'slave_opt'}}) . "' != '" . -# join(" ", @{$slave->[0]->{'start_opts'}}) . "'" ); -# } + # Check if any slave is currently started + my $any_slave_started= 0; + foreach my $mysqld (@{$slave}) + { + if ( $mysqld->{'pid'} ) + { + $any_slave_started= 1; + last; + } + } + + if ($any_slave_started) + { + mtr_verbose("Any slave is started, need to restart"); + $do_slave_restart= 1; + } + elsif ( $tinfo->{'slave_num'} ) + { + mtr_verbose("Test need slave, check for restart"); + $do_slave_restart= 1; + } + } return $do_slave_restart; From 4d56a43cb0895da1d56a0a12421a12307fbbe3cf Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 11:49:31 +0200 Subject: [PATCH 083/235] Only print thesort order debug printout if using script-debug --- mysql-test/lib/mtr_cases.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 344c80ac0bf..d73c7a83dca 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -186,13 +186,13 @@ sub collect_test_cases ($) { @$cases = sort { $sort_criteria{$a->{"name"}} cmp $sort_criteria{$b->{"name"}}; } @$cases; -### For debugging the sort-order - foreach $tinfo (@$cases) + if ( $::opt_script_debug ) { - print $sort_criteria{$tinfo->{"name"}}; - print " -> \t"; - print $tinfo->{"name"}; - print "\n"; + # For debugging the sort-order + foreach $tinfo (@$cases) + { + print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n"); + } } } From 81d423334e3f404ebfb8feca898cb082cbe1f2cb Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 12:46:21 +0200 Subject: [PATCH 084/235] Always need restart for im_* tests --- mysql-test/mysql-test-run.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 31a2c1e32a3..2226c62a262 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3490,6 +3490,11 @@ sub run_testcase_need_master_restart($) $do_restart= 1; # Restart with cluster mtr_verbose("Restart because: Test need cluster"); } + elsif( $tinfo->{'component_id'} eq 'im' ) + { + $do_restart= 1; + mtr_verbose("Restart because: Always restart for im tests"); + } elsif ( $master->[0]->{'running_master_is_special'} and $master->[0]->{'running_master_is_special'}->{'timezone'} eq $tinfo->{'timezone'} and From 7d3887563c6a5ced3b7898474ee9804d902e8f5b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 13:33:12 +0200 Subject: [PATCH 085/235] Modify regex for parsing mysqld version as the mysqld is sometimes a libtool wrapper and the "mysqld --version" command will print "/path/.libs/lt-mysqld Ver x.x.x" mysql-test/mysql-test-run.pl: Modify regex for parsing mysqld version as the mysqld is sometimes a libtool wrapper and the "mysqld --version" command will print "/path/.libs/lt-mysqld" --- mysql-test/mysql-test-run.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 2226c62a262..4eef16e0388 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1177,7 +1177,9 @@ sub check_mysqld_features () { if ( !$mysql_version_id ) { # Look for version - if ( $line =~ /^$exe_mysqld\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ ) + my $exe_name= basename($exe_mysqld); + mtr_verbose("exe_name: $exe_name"); + if ( $line =~ /^\S*$exe_name\s\sVer\s([0-9]*)\.([0-9]*)\.([0-9]*)/ ) { #print "Major: $1 Minor: $2 Build: $3\n"; $mysql_version_id= $1*10000 + $2*100 + $3; From 0fd531ff2853079bc8fdc929a7ecf789c41d05ab Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 14:15:03 +0200 Subject: [PATCH 086/235] Turn on reconnect --- mysql-test/t/im_daemon_life_cycle.imtest | 3 +++ 1 file changed, 3 insertions(+) diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest index acd1f0d887b..7cd4d2bfa83 100644 --- a/mysql-test/t/im_daemon_life_cycle.imtest +++ b/mysql-test/t/im_daemon_life_cycle.imtest @@ -8,6 +8,9 @@ --source include/im_check_env.inc +# Turn on reconnect, not on by default anymore +--enable_reconnect + ########################################################################### # Kill the IM main process and check that the IM Angel will restart the main From e16d9851712b03f3a9dd51d74bd03248798f9e10 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 16:26:17 +0200 Subject: [PATCH 087/235] Fix problem with specifying vardir, mysql_version_id was not yet available when vardir arguments is checked Move the code to look for exe_mysqld earlier => to initial_setup Fix warnings detected by running with "diagnostics" Remove unused option "opt_result_ext" Init "path_ndb_examples_dir" mysql-test/lib/mtr_cases.pl: Set default number of slave to 0 Remove unused/uninitialized "$opt_result_ext" mysql-test/lib/mtr_report.pl: Remove unused/uninitialized "$opt_result_ext" --- mysql-test/lib/mtr_cases.pl | 9 +-- mysql-test/lib/mtr_report.pl | 7 --- mysql-test/mysql-test-run.pl | 108 +++++++++++++++++++++-------------- 3 files changed, 67 insertions(+), 57 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index d73c7a83dca..517a42d88c1 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -250,6 +250,7 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'path'}= $path; $tinfo->{'timezone'}= "GMT-3"; # for UNIX_TIMESTAMP tests to work + $tinfo->{'slave_num'}= 0; # Default, no slave if ( defined mtr_match_prefix($tname,"rpl") ) { if ( $::opt_skip_rpl ) @@ -259,7 +260,8 @@ sub collect_one_test_case($$$$$$$) { return; } - $tinfo->{'slave_num'}= 1; # Default, use one slave + + $tinfo->{'slave_num'}= 1; # Default for rpl* tests, use one slave if ( $tname eq 'rpl_failsafe' or $tname eq 'rpl_chain_temp_table' ) { @@ -346,11 +348,6 @@ sub collect_one_test_case($$$$$$$) { if ( defined $value ) { $tinfo->{'result_file'}= "r/$value.result"; - if ( $::opt_result_ext and $::opt_record or - -f "$tinfo->{'result_file'}$::opt_result_ext") - { - $tinfo->{'result_file'}.= $::opt_result_ext; - } $tinfo->{'master_restart'}= 0; last MASTER_OPT; } diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 6e3796133f2..ab2940b3714 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -53,13 +53,6 @@ sub mtr_show_failed_diff ($) { { $result_file= $eval_file; } - elsif ( $::opt_result_ext and - ( $::opt_record or -f "$result_file$::opt_result_ext" )) - { - # If we have an special externsion for result files we use it if we are - # recording or a result file with that extension exists. - $result_file= "$result_file$::opt_result_ext"; - } my $diffopts= $::opt_udiff ? "-u" : "-c"; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 4eef16e0388..34968f5ebe5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -142,6 +142,8 @@ our $opt_vardir; # A path but set directly on cmd line our $path_vardir_trace; # unix formatted opt_vardir for trace files our $opt_tmpdir; # A path but set directly on cmd line +our $default_vardir; + our $opt_usage; our $opt_suite; @@ -230,8 +232,6 @@ our $opt_ndbconnectstring_slave; our $opt_record; our $opt_check_testcases; -our $opt_result_ext; - our $opt_skip; our $opt_skip_rpl; our $max_slave_num= 0; @@ -471,6 +471,38 @@ sub initial_setup () { $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; $glob_timers= mtr_init_timers(); + + # + # Find the mysqld executable to be able to find the mysqld version + # number as early as possible + # + + # Look for the path where to find the client binaries + $path_client_bindir= mtr_path_exists("$glob_basedir/client", + "$glob_basedir/client_release", + "$glob_basedir/client_debug", + "$glob_basedir/client/release", + "$glob_basedir/client/debug", + "$glob_basedir/bin"); + + # Look for the mysqld executable + $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld", + "$path_client_bindir/mysqld-max-nt", + "$path_client_bindir/mysqld-max", + "$path_client_bindir/mysqld-nt", + "$path_client_bindir/mysqld", + "$path_client_bindir/mysqld-debug", + "$path_client_bindir/mysqld-max", + "$glob_basedir/libexec/mysqld", + "$glob_basedir/sql/release/mysqld", + "$glob_basedir/sql/debug/mysqld"); + + $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; + $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; + + # Use the mysqld found above to find out what features are available + check_mysqld_features(); + } @@ -731,17 +763,20 @@ sub command_line_setup () { # Set the "var/" directory, as it is the base for everything else # -------------------------------------------------------------------------- + $default_vardir= "$glob_mysql_test_dir/var"; if ( ! $opt_vardir ) { - $opt_vardir= "$glob_mysql_test_dir/var"; + $opt_vardir= $default_vardir; } - elsif ( $mysql_version_id < 50000 ) + elsif ( $mysql_version_id < 50000 and + $opt_vardir ne $default_vardir ) { - # --vardir was specified - # It's only supported in 4.1 as a symlink from var/ - # by setting up $opt_mem that will be created + # Version 4.1 and --vardir was specified + # Only supported as a symlink from var/ + # by setting up $opt_mem that symlink will be created $opt_mem= $opt_vardir; - $opt_vardir= undef; + $opt_vardir= $default_vardir; + mtr_report("Using 4.1 vardir trick"); } $path_vardir_trace= $opt_vardir; @@ -1247,8 +1282,8 @@ sub check_mysqld_features () { } # Set default values from mysqld_variables - $opt_socket= %mysqld_variables->{'socket'}; - $default_mysqld_port = %mysqld_variables->{'port'}; + $opt_socket= $mysqld_variables{'socket'}; + $default_mysqld_port = $mysqld_variables{'port'}; } @@ -1269,32 +1304,6 @@ sub executable_setup () { } } - # Look for the path where to find the client binaries - $path_client_bindir= mtr_path_exists("$glob_basedir/client", - "$glob_basedir/client_release", - "$glob_basedir/client_debug", - "$glob_basedir/client/release", - "$glob_basedir/client/debug", - "$glob_basedir/bin"); - - # Look for the mysqld executable - $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld", - "$path_client_bindir/mysqld-max-nt", - "$path_client_bindir/mysqld-max", - "$path_client_bindir/mysqld-nt", - "$path_client_bindir/mysqld", - "$path_client_bindir/mysqld-debug", - "$path_client_bindir/mysqld-max", - "$glob_basedir/libexec/mysqld", - "$glob_basedir/sql/release/mysqld", - "$glob_basedir/sql/debug/mysqld"); - - $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; - $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; - - # Use the mysqld found above to find out what features are available - check_mysqld_features(); - # Look for language files and charsetsdir, use same share my $path_share= mtr_path_exists("$glob_basedir/share", "$glob_basedir/sql/share", @@ -1326,6 +1335,10 @@ sub executable_setup () { "$glob_basedir/server-tools/instance-manager/mysqlmanager", "$glob_basedir/libexec/mysqlmanager"); } + else + { + $exe_im= "not_available"; + } # Look for the client binaries $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); @@ -1365,12 +1378,19 @@ sub executable_setup () { $exe_ndbd= mtr_exe_exists("$ndb_path/src/kernel/ndbd", "$glob_basedir/bin/ndbd"); + + $path_ndb_examples_dir= + mtr_path_exists("$ndb_path/ndbapi-examples", + "$ndb_path/examples"); + $exe_ndb_example= + mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); } # Look for the udf_example library $lib_udf_example= - mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so"); - + mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so", + "$glob_basedir/sql/release/udf_example.dll", + "$glob_basedir/sql/debug/udf_example.dll"); # Look for mysqltest executable if ( $glob_use_embedded_server ) @@ -1468,11 +1488,11 @@ sub environment_setup () { } $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', $ENV{'LD_LIBRARY_PATH'})); + split(':', qw($ENV{'LD_LIBRARY_PATH'}))); mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}"); $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', $ENV{'DYLD_LIBRARY_PATH'})); + split(':', qw($ENV{'DYLD_LIBRARY_PATH'}))); mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}"); @@ -1798,7 +1818,7 @@ sub cleanup_stale_files () { mtr_report("Removing Stale Files"); - if ( $opt_vardir eq "$glob_mysql_test_dir/var" ) + if ( $opt_vardir eq $default_vardir ) { # # Running with "var" in mysql-test dir @@ -1838,7 +1858,7 @@ sub cleanup_stale_files () { # Remove the var/ dir in mysql-test dir if any # this could be an old symlink that shouldn't be there - rmtree("$glob_mysql_test_dir/var"); + rmtree($default_vardir); # Remove the "var" dir rmtree("$opt_vardir/"); @@ -1849,7 +1869,7 @@ sub cleanup_stale_files () { # Runinng with var as a link to some "memory" location, normally tmpfs rmtree($opt_mem); mkpath($opt_mem); - mtr_verbose("Creating symlink from $opt_vardir to $opt_mem"); + mtr_report("Creating symlink from $opt_vardir to $opt_mem"); symlink($opt_mem, $opt_vardir); # Put a small file to recognize this dir was created by --mem mtr_tofile($created_by_mem_file, $opt_mem); @@ -2710,7 +2730,7 @@ sub do_before_run_mysqltest($) # Remove old files produced by mysqltest my $result_dir= "r"; - if ( ! $opt_suite eq "main" ) + if ( $opt_suite ne "main" ) { $result_dir= "suite/$opt_suite/r"; } From eccf9e2851444424dc9cf676d95255a92056aeca Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 16:40:00 +0200 Subject: [PATCH 088/235] Remove commented out testcases from disabled.def Remove the im_* test, they are fixed according to the referenced bugs --- mysql-test/t/disabled.def | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 8c4a76c78a9..1c2503e3240 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -9,29 +9,19 @@ # Do not use any TAB characters for whitespace. # ############################################################################## -#events_bugs : BUG#17619 2006-02-21 andrey Race conditions -#events_stress : BUG#17619 2006-02-21 andrey Race conditions -#events : BUG#17619 2006-02-21 andrey Race conditions -#events_scheduling : BUG#19170 2006-04-26 andrey Test case of 19170 fails on some platforms. Has to be checked. im_options : Bug#20294 2006-07-24 stewart Instance manager test im_options fails randomly -#im_life_cycle : Bug#20368 2006-06-10 alik im_life_cycle test fails -im_daemon_life_cycle : BUG#22379 2006-09-15 ingo im_daemon_life_cycle.test fails on merge of 5.1 -> 5.1-engines -im_instance_conf : BUG#20294 2006-09-16 ingo Instance manager test im_instance_conf fails randomly concurrent_innodb : BUG#21579 2006-08-11 mleich innodb_concurrent random failures with varying differences ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog -#ndb_binlog_ignore_db : BUG#21279 2006-07-25 ingo Randomly throws a warning ndb_load : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table ps : BUG#21524 2006-08-08 pgalbraith 'ps' test fails in --ps-protocol test AMD64 bit ps_7ndb : BUG#18950 2006-02-16 jmiller create table like does not obtain LOCK_open rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2myisam : BUG#19227 Seems to pass currently -#rpl_ndb_commit_afterflush : BUG#19328 2006-05-04 tomas Slave timeout with COM_REGISTER_SLAVE error causing stop rpl_ndb_dd_partitions : BUG#19259 2006-04-21 rpl_ndb_dd_partitions fails on s/AMD rpl_ndb_ddl : BUG#18946 result file needs update + test needs to checked rpl_ndb_innodb2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement -#rpl_ndb_log : BUG#18947 2006-03-21 tomas CRBR: order in binlog of create table and insert (on different table) not determ rpl_ndb_myisam2ndb : Bug #19710 Cluster replication to partition table fails on DELETE FROM statement rpl_row_blob_innodb : BUG#18980 2006-04-10 kent Test fails randomly rpl_sp : BUG#16456 2006-02-16 jmiller @@ -39,8 +29,5 @@ rpl_multi_engine : BUG#22583 2006-09-23 lars # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open #ndb_binlog_ddl_multi : BUG#18976 2006-04-10 kent CRBR: multiple binlog, second binlog may miss schema log events -#rpl_ndb_idempotent : BUG#21298 2006-07-27 msvensson -#rpl_row_basic_7ndb : BUG#21298 2006-07-27 msvensson -#rpl_truncate_7ndb : BUG#21298 2006-07-27 msvensson ndb_binlog_discover : bug#21806 2006-08-24 ndb_autodiscover3 : bug#21806 From 64329b16ecbb75b4934741ad3083b09b3c94f27c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 6 Oct 2006 17:15:26 +0200 Subject: [PATCH 089/235] Add error handling of failure to start server to "run_testcase_start_servers" mysql-test/lib/mtr_report.pl: Use tinfo's comment as primary place to look for error message --- mysql-test/lib/mtr_report.pl | 8 +++--- mysql-test/mysql-test-run.pl | 48 +++++++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index ab2940b3714..4708de92e07 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -144,9 +144,11 @@ sub mtr_report_test_failed ($) { print "[ fail ]\n"; } - # FIXME Instead of this test, and meaningless error message in 'else' - # we should write out into $::path_timefile when the error occurs. - if ( -f $::path_timefile ) + if ( $tinfo->{'comment'} ) + { + print "\nERROR: $tinfo->{'comment'}\n"; + } + elsif ( -f $::path_timefile ) { print "\nErrors are (from $::path_timefile) :\n"; print mtr_fromfile($::path_timefile); # FIXME print_file() instead diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 34968f5ebe5..5ba42fb2c25 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2775,6 +2775,9 @@ sub do_after_run_mysqltest($) mtr_appendfile_to_file($path_timefile, $path_mysqltest_log) if -f $path_timefile; + # Remove the file that mysqltest writes info to + unlink($path_timefile); + } @@ -2807,7 +2810,12 @@ sub run_testcase ($) { my $died= mtr_record_dead_children(); if ($died or $master_restart or $slave_restart) { - run_testcase_start_servers($tinfo); + if (run_testcase_start_servers($tinfo)) + { + mtr_report_test_name($tinfo); + report_failure_and_restart($tinfo); + return 1; + } } # ---------------------------------------------------------------------- @@ -3748,6 +3756,17 @@ sub run_testcase_stop_servers($$$) { } } + +# +# run_testcase_start_servers +# +# Start the servers neede by this test case +# +# RETURN +# 0 OK +# 1 Start failed +# + sub run_testcase_start_servers($) { my $tinfo= shift; @@ -3755,7 +3774,7 @@ sub run_testcase_start_servers($) { if ( $glob_use_running_server or $glob_use_embedded_server ) { - return; + return 0; } # ------------------------------------------------------- @@ -3796,10 +3815,9 @@ sub run_testcase_start_servers($) { $master->[0]->{'start_timeout'}, $master->[0]->{'pid'})) { - mtr_report_test_name($tinfo); - mtr_report("Failed to create 'cluster/apply_status' table"); - report_failure_and_restart($tinfo); - return; + + $tinfo->{'comment'}= "Failed to create 'cluster/apply_status' table"; + return 1; } } mtr_tofile($master->[1]->{'path_myerr'},"CURRENT_TEST: $tname\n"); @@ -3822,13 +3840,10 @@ sub run_testcase_start_servers($) { im_create_defaults_file($instance_manager); - unless ( mtr_im_start($instance_manager, $tinfo->{im_opts}) ) + if ( ! mtr_im_start($instance_manager, $tinfo->{im_opts}) ) { - mtr_report_test_name($tinfo); - report_failure_and_restart($tinfo); - mtr_report("Failed to start Instance Manager. " . - "The test '$tname' is marked as failed."); - return; + $tinfo->{'comment'}= "Failed to start Instance Manager. "; + return 1; } } @@ -3878,7 +3893,8 @@ sub run_testcase_start_servers($) { if (ndbcluster_wait_started($cluster, "")) { # failed to start - mtr_report("Start of $cluster->{'name'} cluster failed, "); + $tinfo->{'comment'}= "Start of $cluster->{'name'} cluster failed"; + return 1; } } @@ -3890,9 +3906,13 @@ sub run_testcase_start_servers($) { if (mysqld_wait_started($mysqld)) { - mtr_warning("Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}"); + # failed to start + $tinfo->{'comment'}= + "Failed to start $mysqld->{'type'} mysqld $mysqld->{'idx'}"; + return 1; } } + return 0; } # From 40e44f0e569106c72c3734e8b94cd1f1c9bc5337 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Oct 2006 19:09:40 +0200 Subject: [PATCH 090/235] Two implementations of "get_err_code_from_name", one use if mysqld_ername.h is available and oe if it's not Declare "to_ptr" first in block --- client/mysqltest.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 8d8c20c3e8f..a9ac286aa88 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2472,17 +2472,13 @@ static st_error global_error_names[] = #include { 0, 0 } }; -#define HAVE_MYSQLD_ERNAME -#endif - uint get_errcode_from_name(char *error_name, char *error_end) { - DBUG_ENTER("get_errcode_from_name"); -#ifdef HAVE_MYSQLD_ERNAME - /* SQL error as string */ st_error *e= global_error_names; + + DBUG_ENTER("get_errcode_from_name"); DBUG_PRINT("enter", ("error_name: %s", error_name)); /* Loop through the array of known error names */ @@ -2501,13 +2497,17 @@ uint get_errcode_from_name(char *error_name, char *error_end) } if (!e->name) die("Unknown SQL error name '%s'", error_name); -#else - LINT_INIT(error_name); - LINT_INIT(error_end); - abort_not_in_this_version(); -#endif - DBUG_RETURN(0);; + DBUG_RETURN(0); } +#else +uint get_errcode_from_name(char *error_name __attribute__((unused)), + char *error_end __attribute__((unused))) +{ + abort_not_in_this_version(); + return 0; /* Never reached */ +} +#endif + void do_get_errcodes(struct st_command *command) @@ -2536,6 +2536,8 @@ void do_get_errcodes(struct st_command *command) if (*p == 'S') { + char *to_ptr= to->code.sqlstate; + /* SQLSTATE string - Must be SQLSTATE_LENGTH long @@ -2546,7 +2548,6 @@ void do_get_errcodes(struct st_command *command) die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH); /* Check sqlstate string validity */ - char *to_ptr= to->code.sqlstate; while (*p && p != end) { if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p)) From 5adb9347eaadaed914accca7372378f62ed5330e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Oct 2006 19:11:37 +0200 Subject: [PATCH 091/235] Improve sort algorithm for reorder, all test with smae name except for ending digit should be run after each other. Example of that is ndb_autodiscover[1-3] --- mysql-test/lib/mtr_cases.pl | 68 +++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 517a42d88c1..435ea73e8a3 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -143,7 +143,7 @@ sub collect_test_cases ($) { { next; } - + next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test); collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, @@ -159,37 +159,71 @@ sub collect_test_cases ($) { { my %sort_criteria; - my $tinfo; # Make a mapping of test name to a string that represents how that test # should be sorted among the other tests. Put the most important criterion # first, then a sub-criterion, then sub-sub-criterion, et c. - foreach $tinfo (@$cases) + foreach my $tinfo (@$cases) { - my @this_criteria = (); + my @criteria = (); - # - # Append the criteria for sorting, in order of importance. - # + # Look for tests that muct be in run in a defined order + # that is defined by test having the same name except for + # the ending digit - push(@this_criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); - push(@this_criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); - # Group test with similar options together. - # Ending with "~" makes empty sort later than filled - push(@this_criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); + # Put variables into hash + my $test_name= $tinfo->{'name'}; + my $depend_on_test_name; + if ( $test_name =~ /^([\D]+)([0-9]{1})$/ ) + { + my $base_name= $1; + my $idx= $2; + mtr_verbose("$test_name => $base_name idx=$idx"); + if ( $idx > 1 ) + { + $idx-= 1; + $base_name= "$base_name$idx"; + mtr_verbose("New basename $base_name"); + } - # Finally, order by the name - push(@this_criteria, $tinfo->{'name'}); + foreach my $tinfo2 (@$cases) + { + if ( $tinfo2->{'name'} eq $base_name ) + { + mtr_verbose("found dependent test $tinfo2->{'name'}"); + $depend_on_test_name=$base_name; + } + } + } - $sort_criteria{$tinfo->{"name"}} = join(" ", @this_criteria); + if ( defined $depend_on_test_name ) + { + mtr_verbose("Giving $test_name same critera as $depend_on_test_name"); + $sort_criteria{$test_name} = $sort_criteria{$depend_on_test_name}; + } + else + { + # + # Append the criteria for sorting, in order of importance. + # + push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); + push(@criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); + # Group test with equal options together. + # Ending with "~" makes empty sort later than filled + push(@criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); + + $sort_criteria{$test_name} = join(" ", @criteria); + } } - @$cases = sort { $sort_criteria{$a->{"name"}} cmp $sort_criteria{$b->{"name"}}; } @$cases; + @$cases = sort { + $sort_criteria{$a->{'name'}} . $a->{'name'} cmp + $sort_criteria{$b->{'name'}} . $b->{'name'}; } @$cases; if ( $::opt_script_debug ) { # For debugging the sort-order - foreach $tinfo (@$cases) + foreach my $tinfo (@$cases) { print("$sort_criteria{$tinfo->{'name'}} -> \t$tinfo->{'name'}\n"); } From 4f7097035f4f2ac4059dbbebdd6b4648b4e7b6e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Oct 2006 19:47:42 +0200 Subject: [PATCH 092/235] Add comment and remove strange assignment in 'do_exec' --- client/mysqltest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index a9ac286aa88..b89c763de13 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1498,6 +1498,7 @@ void do_exec(struct st_command *command) DBUG_ENTER("do_exec"); DBUG_PRINT("enter", ("cmd: '%s'", cmd)); + /* Skip leading space */ while (*cmd && my_isspace(charset_info, *cmd)) cmd++; if (!*cmd) @@ -1507,7 +1508,6 @@ void do_exec(struct st_command *command) init_dynamic_string(&ds_cmd, 0, command->query_len+256, 256); /* Eval the command, thus replacing all environment variables */ do_eval(&ds_cmd, cmd, command->end, TRUE); - cmd= ds_cmd.str; DBUG_PRINT("info", ("Executing '%s' as '%s'", command->first_argument, cmd)); From 13da57d0f15cf6a63c34010df530455da63bb2b0 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Oct 2006 20:14:21 +0200 Subject: [PATCH 093/235] Init "saved_expected_errors" at program start, avoids crash where --error is first command strcmp -> strncmp --- client/mysqltest.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index b89c763de13..3d457261980 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2544,11 +2544,11 @@ void do_get_errcodes(struct st_command *command) - May contain only digits[0-9] and _uppercase_ letters */ p++; /* Step past the S */ - if (end - p != SQLSTATE_LENGTH) + if ((end - p) != SQLSTATE_LENGTH) die("The sqlstate must be exactly %d chars long", SQLSTATE_LENGTH); /* Check sqlstate string validity */ - while (*p && p != end) + while (*p && p < end) { if (my_isdigit(charset_info, *p) || my_isupper(charset_info, *p)) *to_ptr++= *p++; @@ -4652,7 +4652,8 @@ void handle_error(struct st_command *command, */ if (err_errno == CR_SERVER_LOST || err_errno == CR_SERVER_GONE_ERROR) - die("require query '%s' failed: %d: %s", command->query, err_errno, err_error); + die("require query '%s' failed: %d: %s", command->query, + err_errno, err_error); /* Abort the run of this test, pass the failed query as reason */ abort_not_supported_test("Query '%s' failed, required functionality" \ @@ -4669,8 +4670,8 @@ void handle_error(struct st_command *command, if (((command->expected_errors.err[i].type == ERR_ERRNO) && (command->expected_errors.err[i].code.errnum == err_errno)) || ((command->expected_errors.err[i].type == ERR_SQLSTATE) && - (strcmp(command->expected_errors.err[i].code.sqlstate, - err_sqlstate) == 0))) + (strncmp(command->expected_errors.err[i].code.sqlstate, + err_sqlstate, SQLSTATE_LENGTH) == 0))) { if (!disable_result_log) { @@ -4695,7 +4696,7 @@ void handle_error(struct st_command *command, } DBUG_PRINT("info",("i: %d expected_errors: %d", i, - command->expected_errors)); + command->expected_errors.count)); if (!disable_result_log) { @@ -5423,6 +5424,9 @@ int main(int argc, char **argv) save_file[0]= 0; TMPDIR[0]= 0; + /* Init expected errors */ + memset(&saved_expected_errors, 0, sizeof(saved_expected_errors)); + /* Init connections */ memset(connections, 0, sizeof(connections)); connections_end= connections + From 9e4e7023a2978612c243e4cbc755dbe0d32adb20 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Oct 2006 20:16:57 +0200 Subject: [PATCH 094/235] Fix spelling error --- mysql-test/t/rpl_slave_status.test | 2 +- mysql-test/t/system_mysql_db_fix.test | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mysql-test/t/rpl_slave_status.test b/mysql-test/t/rpl_slave_status.test index 67d3816f443..cb12198bae2 100644 --- a/mysql-test/t/rpl_slave_status.test +++ b/mysql-test/t/rpl_slave_status.test @@ -9,7 +9,7 @@ start slave; connection master; --disable_warnings drop table if exists t1; ---enable_warning +--enable_warnings create table t1 (n int); insert into t1 values (1); save_master_pos; diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test index dc3047a8564..5e8822569b7 100644 --- a/mysql-test/t/system_mysql_db_fix.test +++ b/mysql-test/t/system_mysql_db_fix.test @@ -27,7 +27,7 @@ CREATE TABLE db ( KEY User (User) ) type=ISAM; ---enable-warnings +--enable_warnings INSERT INTO db VALUES ('%','test', '','Y','Y','Y','Y','Y','Y'); INSERT INTO db VALUES ('%','test\_%','','Y','Y','Y','Y','Y','Y'); @@ -45,7 +45,7 @@ CREATE TABLE host ( PRIMARY KEY Host (Host,Db) ) type=ISAM; ---enable-warnings +--enable_warnings --disable_warnings CREATE TABLE user ( @@ -64,7 +64,7 @@ CREATE TABLE user ( PRIMARY KEY Host (Host,User) ) type=ISAM; ---enable-warnings +--enable_warnings INSERT INTO user VALUES ('localhost','root','','Y','Y','Y','Y','Y','Y','Y','Y','Y'); INSERT INTO user VALUES ('localhost','', '','N','N','N','N','N','N','N','N','N'); From 7310834c6a0ac561f666d1e31e5d8600398f5abb Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 7 Oct 2006 20:22:25 +0200 Subject: [PATCH 095/235] Update result format --- mysql-test/r/binlog_row_mix_innodb_myisam.result | 2 +- mysql-test/r/rpl_ndb_sp003.result | 2 +- mysql-test/r/rpl_row_sp003.result | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/binlog_row_mix_innodb_myisam.result b/mysql-test/r/binlog_row_mix_innodb_myisam.result index ae66f98739d..60b456571e6 100644 --- a/mysql-test/r/binlog_row_mix_innodb_myisam.result +++ b/mysql-test/r/binlog_row_mix_innodb_myisam.result @@ -220,7 +220,7 @@ select (@before:=unix_timestamp())*0; (@before:=unix_timestamp())*0 0 begin; - select * from t1 for update; +select * from t1 for update; insert into t2 values (20); ERROR HY000: Lock wait timeout exceeded; try restarting transaction select (@after:=unix_timestamp())*0; diff --git a/mysql-test/r/rpl_ndb_sp003.result b/mysql-test/r/rpl_ndb_sp003.result index 94f320f387b..d7922c61b52 100644 --- a/mysql-test/r/rpl_ndb_sp003.result +++ b/mysql-test/r/rpl_ndb_sp003.result @@ -21,7 +21,7 @@ END| SELECT get_lock("test", 200); get_lock("test", 200) 1 - CALL test.p1(); +CALL test.p1(); CALL test.p2(); SELECT release_lock("test"); release_lock("test") diff --git a/mysql-test/r/rpl_row_sp003.result b/mysql-test/r/rpl_row_sp003.result index 01e352c3d46..df3e2a7ceed 100644 --- a/mysql-test/r/rpl_row_sp003.result +++ b/mysql-test/r/rpl_row_sp003.result @@ -21,7 +21,7 @@ END| SELECT get_lock("test", 200); get_lock("test", 200) 1 - CALL test.p1(); +CALL test.p1(); CALL test.p2(); SELECT release_lock("test"); release_lock("test") From 96c801f1a7a94ca6f486114738820f2faa7392dd Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Oct 2006 15:50:16 +0200 Subject: [PATCH 096/235] Reorder the order of feature checks a bit Make the mysqld_variables hash global so it can be used throughout the program --- mysql-test/mysql-test-run.pl | 103 ++++++++++++++++++++++------------- 1 file changed, 64 insertions(+), 39 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5ba42fb2c25..309c82ef8f2 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -311,8 +311,8 @@ our $used_binlog_format; our $debug_compiled_binaries; our $glob_tot_real_time= 0; -# Default values read from mysqld -our $default_mysqld_port; +our %mysqld_variables; + ###################################################################### # @@ -368,7 +368,13 @@ sub main () { initial_setup(); command_line_setup(); + + check_ndbcluster_support(\%mysqld_variables); + check_ssl_support(\%mysqld_variables); + check_debug_support(\%mysqld_variables); + executable_setup(); + environment_setup(); signal_setup(); @@ -501,7 +507,7 @@ sub initial_setup () { $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; # Use the mysqld found above to find out what features are available - check_mysqld_features(); + collect_mysqld_features(); } @@ -721,7 +727,6 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Find out type of logging that are being used # -------------------------------------------------------------------------- - # NOTE if the default binlog format is changed, this has to be changed $used_binlog_format= "stmt"; foreach my $arg ( @opt_extra_mysqld_opt ) @@ -762,7 +767,6 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Set the "var/" directory, as it is the base for everything else # -------------------------------------------------------------------------- - $default_vardir= "$glob_mysql_test_dir/var"; if ( ! $opt_vardir ) { @@ -792,25 +796,46 @@ sub command_line_setup () { } # -------------------------------------------------------------------------- - # If not set, set these to defaults + # Set tmpdir # -------------------------------------------------------------------------- - $opt_tmpdir= "$opt_vardir/tmp" unless $opt_tmpdir; $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any # -------------------------------------------------------------------------- - # Do sanity checks of command line arguments + # Set socket # -------------------------------------------------------------------------- + if (!$opt_socket) + { + $opt_socket= $mysqld_variables{'socket'}; + } # -------------------------------------------------------------------------- - # Look at the command line options and set script flags + # Check im suport # -------------------------------------------------------------------------- + if ( $mysql_version_id < 50000 ) + { + # Instance manager is not supported until 5.0 + $opt_skip_im= 1; + } + + if ( $glob_win32 ) + { + mtr_report("Disable Instance manager - not supported on Windows"); + $opt_skip_im= 1; + } + + # -------------------------------------------------------------------------- + # Record flag + # -------------------------------------------------------------------------- if ( $opt_record and ! @opt_cases ) { mtr_error("Will not run in record mode without a specific test case"); } + # -------------------------------------------------------------------------- + # Embedded server flag + # -------------------------------------------------------------------------- if ( $opt_embedded_server ) { $glob_use_embedded_server= 1; @@ -825,11 +850,18 @@ sub command_line_setup () { } } + + # -------------------------------------------------------------------------- + # ps protcol flag + # -------------------------------------------------------------------------- if ( $opt_ps_protocol ) { push(@glob_test_mode, "ps-protocol"); } + # -------------------------------------------------------------------------- + # Ndb cluster flags + # -------------------------------------------------------------------------- if ( $opt_with_ndbcluster and $opt_skip_ndbcluster) { mtr_error("Can't specify both --with-ndbcluster and --skip-ndbcluster"); @@ -865,22 +897,33 @@ sub command_line_setup () { $opt_ndbconnectstring_slave= "host=localhost:$opt_ndbcluster_port_slave"; } + # -------------------------------------------------------------------------- + # Bench flags + # -------------------------------------------------------------------------- if ( $opt_small_bench ) { $opt_bench= 1; } + # -------------------------------------------------------------------------- + # Sleep flag + # -------------------------------------------------------------------------- if ( $opt_sleep ) { $opt_sleep_time_after_restart= $opt_sleep; } + # -------------------------------------------------------------------------- + # Gcov flag + # -------------------------------------------------------------------------- if ( $opt_gcov and ! $opt_source_dist ) { mtr_error("Coverage test needs the source - please use source dist"); } + # -------------------------------------------------------------------------- # Check debug related options + # -------------------------------------------------------------------------- if ( $opt_gdb || $opt_client_gdb || $opt_ddd || $opt_client_ddd || $opt_manual_gdb || $opt_manual_ddd || $opt_manual_debug || $opt_debugger || $opt_client_debugger ) @@ -895,13 +938,9 @@ sub command_line_setup () { } } - # Check IM arguments - if ( $glob_win32 ) - { - mtr_report("Disable Instance manager - not supported on Windows"); - $opt_skip_im= 1; - } + # -------------------------------------------------------------------------- # Check valgrind arguments + # -------------------------------------------------------------------------- if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options) { mtr_report("Turning on valgrind for all executables"); @@ -1185,7 +1224,7 @@ sub datadir_setup () { ############################################################################## -sub check_mysqld_features () { +sub collect_mysqld_features () { # # Execute "mysqld --no-defaults --help --verbose", that will # print out version and a list of all features and settings @@ -1202,7 +1241,6 @@ sub check_mysqld_features () { $exe_mysqld); } - my %mysqld_variables; my $F= IO::File->new($spec_file) or mtr_error("can't open file \"$spec_file\": $!"); @@ -1263,27 +1301,6 @@ sub check_mysqld_features () { mtr_error("Could not find version of MySQL") unless $mysql_version_id; mtr_error("Could not find variabes list") unless $found_variable_list_start; - check_ndbcluster_support(\%mysqld_variables); - check_ssl_support(\%mysqld_variables); - check_debug_support(\%mysqld_variables); - - if ( $mysql_version_id < 50000 ) - { - # Instance manager is not supported until 5.0 - $opt_skip_im= 1; - - } - - if ( $mysql_version_id < 50100 ) - { - # Slave cluster is not supported until 5.1 - $opt_skip_ndbcluster_slave= 1; - - } - - # Set default values from mysqld_variables - $opt_socket= $mysqld_variables{'socket'}; - $default_mysqld_port = $mysqld_variables{'port'}; } @@ -1516,7 +1533,7 @@ sub environment_setup () { $ENV{'SLAVE_MYPORT'}= $slave->[0]->{'port'}; $ENV{'SLAVE_MYPORT1'}= $slave->[1]->{'port'}; $ENV{'SLAVE_MYPORT2'}= $slave->[2]->{'port'}; - $ENV{'MYSQL_TCP_PORT'}= $default_mysqld_port; + $ENV{'MYSQL_TCP_PORT'}= $mysqld_variables{'port'}; $ENV{MTR_BUILD_THREAD}= 0 unless $ENV{MTR_BUILD_THREAD}; # Set if not set @@ -2006,6 +2023,14 @@ sub check_ndbcluster_support ($) { } $opt_ndbcluster_supported= 1; mtr_report("Using ndbcluster when necessary, mysqld supports it"); + + if ( $mysql_version_id < 50100 ) + { + # Slave cluster is not supported until 5.1 + $opt_skip_ndbcluster_slave= 1; + + } + return; } From 4404ea6418c6af05b093db313905c7cdd267be75 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Oct 2006 16:11:55 +0200 Subject: [PATCH 097/235] When looking for client binary directories it necessary to look for the one s that are "deep down" first. --- mysql-test/mysql-test-run.pl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 309c82ef8f2..7b9a55053f0 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -484,11 +484,11 @@ sub initial_setup () { # # Look for the path where to find the client binaries - $path_client_bindir= mtr_path_exists("$glob_basedir/client", + $path_client_bindir= mtr_path_exists("$glob_basedir/client/release", + "$glob_basedir/client/debug", + "$glob_basedir/client", "$glob_basedir/client_release", "$glob_basedir/client_debug", - "$glob_basedir/client/release", - "$glob_basedir/client/debug", "$glob_basedir/bin"); # Look for the mysqld executable From 3651933d0932e3870f1bb66bb6373e3d113ad6ad Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Oct 2006 16:19:23 +0200 Subject: [PATCH 098/235] vsnprintf is not available on win2003-x86 host, as this is just a debug functionality - disable it for now. --- client/mysqltest.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3d457261980..3f8bc99bdf8 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -728,9 +728,11 @@ void die(const char *fmt, ...) if (fmt) { #ifdef DBUG_ON +#ifndef __WIN__ char buff[256]; vsnprintf(buff, sizeof(buff), fmt, args); DBUG_PRINT("error", ("%s", buff)); +#endif #endif fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) @@ -855,8 +857,10 @@ void warning_msg(const char *fmt, ...) dynstr_append_mem(&ds_warning_messages, buff, len); } +#ifndef __WIN__ len= vsnprintf(buff, sizeof(buff), fmt, args); dynstr_append_mem(&ds_warning_messages, buff, len); +#endif dynstr_append(&ds_warning_messages, "\n"); va_end(args); From 127e4011853a59647c7cc8e8f0f5e662a9658a16 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Oct 2006 17:05:17 +0200 Subject: [PATCH 099/235] Move list of mysqls src dirs into lib/mtr_gcov.pl as it's only used from there --- mysql-test/lib/mtr_gcov.pl | 18 +++++++++++++++++- mysql-test/mysql-test-run.pl | 16 ---------------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/mysql-test/lib/mtr_gcov.pl b/mysql-test/lib/mtr_gcov.pl index 07aac1d2017..71d3d6a2a43 100644 --- a/mysql-test/lib/mtr_gcov.pl +++ b/mysql-test/lib/mtr_gcov.pl @@ -23,12 +23,28 @@ sub gcov_prepare () { -or -name \*.da | xargs rm`; } +# Used by gcov +our @mysqld_src_dirs= + ( + "strings", + "mysys", + "include", + "extra", + "regex", + "isam", + "merge", + "myisam", + "myisammrg", + "heap", + "sql", + ); + sub gcov_collect () { print "Collecting source coverage info...\n"; -f $::opt_gcov_msg and unlink($::opt_gcov_msg); -f $::opt_gcov_err and unlink($::opt_gcov_err); - foreach my $d ( @::mysqld_src_dirs ) + foreach my $d ( @mysqld_src_dirs ) { chdir("$::glob_basedir/$d"); foreach my $f ( (glob("*.h"), glob("*.cc"), glob("*.c")) ) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7b9a55053f0..6bb069a11f5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -87,22 +87,6 @@ require "lib/mtr_stress.pl"; $Devel::Trace::TRACE= 1; -# Used by gcov -our @mysqld_src_dirs= - ( - "strings", - "mysys", - "include", - "extra", - "regex", - "isam", - "merge", - "myisam", - "myisammrg", - "heap", - "sql", - ); - ############################################################################## # # Default settings From ddf7e2a5f01bbffc93b3b3440e12b154899d8cb0 Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Oct 2006 17:08:24 +0200 Subject: [PATCH 100/235] Do the check of special mysqld exe for master or slave after command line args have been parsed --- mysql-test/mysql-test-run.pl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 6bb069a11f5..40b0efd4971 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -487,9 +487,6 @@ sub initial_setup () { "$glob_basedir/sql/release/mysqld", "$glob_basedir/sql/debug/mysqld"); - $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; - $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; - # Use the mysqld found above to find out what features are available collect_mysqld_features(); @@ -922,6 +919,12 @@ sub command_line_setup () { } } + # -------------------------------------------------------------------------- + # Check if special exe was selected for master or slave + # -------------------------------------------------------------------------- + $exe_master_mysqld= $exe_master_mysqld || $exe_mysqld; + $exe_slave_mysqld= $exe_slave_mysqld || $exe_mysqld; + # -------------------------------------------------------------------------- # Check valgrind arguments # -------------------------------------------------------------------------- From eab94fd0ba53ed78c5104bfea7e48bb29c26126a Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 8 Oct 2006 17:48:01 +0200 Subject: [PATCH 101/235] Print names of testcases that failed check_testcase, this makes it easier to run the whole testcase to find wich testcases need to be checked more carefully and the just "copy and paste" the suspicious test case names to a new mysql-test-run.pl command. mysql-test/mysql-test-run.pl: Mark test cases that fails "check_testcase" Make run_check_testcase return value indicating if check failed mysql-test/include/check-testcase.test: New BitKeeper file ``mysql-test/include/check-testcase.test'' --- mysql-test/include/check-testcase.test | 49 ++++++++++++++++++++++++++ mysql-test/lib/mtr_report.pl | 26 +++++++++++++- mysql-test/mysql-test-run.pl | 11 +++++- 3 files changed, 84 insertions(+), 2 deletions(-) create mode 100644 mysql-test/include/check-testcase.test diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test new file mode 100644 index 00000000000..d67e73470b0 --- /dev/null +++ b/mysql-test/include/check-testcase.test @@ -0,0 +1,49 @@ +# +# This test is executed twice for each test case if mysql-test-run is passed +# the flag --check-testcase. +# Before every testcase it's run with mysqltest in record mode and will +# thus produce an output file +# that can be compared to output from after the tescase. +# In that way it's possible to check that a testcase does not have +# any unwanted side affects. +# + +# +# Dump all global variables +# +show global variables; + +# +# Dump all databases +# +show databases; + +# +# Dump the "test" database, all it's tables and their data +# +--exec $MYSQL_DUMP --skip-comments test + +# +# Dump the "mysql" database and it's tables +# Select data separately to add "order by" +# +--exec $MYSQL_DUMP --skip-comments --no-data mysql +use mysql; +select * from columns_priv; +select * from db order by host, db, user; +select * from func; +select * from help_category; +select * from help_keyword; +select * from help_relation; +select * from help_relation; +select * from host; +select * from tables_priv; +select * from time_zone; +select * from time_zone_leap_second; +select * from time_zone_name; +select * from time_zone_transition; +select * from time_zone_transition_type; +select * from user; + + + diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index 4708de92e07..ec1bed9671b 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -172,7 +172,7 @@ sub mtr_report_stats ($) { my $tot_failed= 0; my $tot_tests= 0; my $tot_restarts= 0; - my $found_problems= 0; # Some warnings are errors... + my $found_problems= 0; # Some warnings in the logfiles are errors... foreach my $tinfo (@$tests) { @@ -283,6 +283,7 @@ sub mtr_report_stats ($) { print "\n"; + # Print a list of testcases that failed if ( $tot_failed != 0 ) { my $test_mode= join(" ", @::glob_test_mode) || "default"; @@ -296,7 +297,30 @@ sub mtr_report_stats ($) { } } print "\n"; + } + + # Print a list of check_testcases that failed(if any) + if ( $::opt_check_testcases ) + { + my @check_testcases= (); + + foreach my $tinfo (@$tests) + { + if ( defined $tinfo->{'check_testcase_failed'} ) + { + push(@check_testcases, $tinfo->{'name'}); + } + } + + if ( @check_testcases ) + { + print "Check of testcase failed for: "; + print join(" ", @check_testcases); + print "\n\n"; + } + } + if ( $tot_failed != 0 || $found_problems) { mtr_error("there where failing test cases"); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 40b0efd4971..c53ca49a7e9 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -3932,6 +3932,10 @@ sub run_testcase_start_servers($) { # Before a testcase, run in record mode, save result file to var # After testcase, run and compare with the recorded file, they should be equal! # +# RETURN VALUE +# 0 OK +# 1 Check failed +# sub run_check_testcase ($$) { my $mode= shift; @@ -3976,6 +3980,7 @@ sub run_check_testcase ($$) { { mtr_error("Could not execute 'check-testcase' $mode testcase"); } + return $res; } @@ -4165,7 +4170,11 @@ sub run_mysqltest ($) { { if ($mysqld->{'pid'}) { - run_check_testcase("after", $mysqld); + if (run_check_testcase("after", $mysqld)) + { + # Check failed, mark the test case with that info + $tinfo->{'check_testcase_failed'}= 1; + } } } } From c6a67e69331762f1e9e2ba725cb418c4d87a8a27 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Oct 2006 21:13:37 +0200 Subject: [PATCH 102/235] Bug#23010 _my_b_read() passing illegal file handles to my_seek() - The io cache flag seek_not_done was not set properly in the reinit_ io_chache function call and this led my_seek to be called despite an invalid file handle. - Added a test in reinit_io_cache to ensure we have a valid file handle before setting seek_not_done flag. mysys/mf_iocache.c: Added a test to only trigger my_seek function calls if we have a valid file descriptor. mysys/my_seek.c: Refactored incomplete condition into an assertion. This also ensures that newpos is initialized. --- mysys/mf_iocache.c | 6 +++++- mysys/my_seek.c | 9 +++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index cd2a140182e..eb8b992c601 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -333,7 +333,11 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type, { info->read_end=info->write_pos; info->end_of_file=my_b_tell(info); - info->seek_not_done=1; + /* + Trigger a new seek only if we have a valid + file handle. + */ + info->seek_not_done= (info->file != -1); } else if (type == WRITE_CACHE) { diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 8035312496d..006d0013695 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -29,8 +29,13 @@ my_off_t my_seek(File fd, my_off_t pos, int whence, whence, MyFlags)); DBUG_ASSERT(pos != MY_FILEPOS_ERROR); /* safety check */ - if (-1 != fd) - newpos=lseek(fd, pos, whence); + /* + Make sure we are using a valid file descriptor! + */ + DBUG_ASSERT(fd != -1); + + newpos= lseek(fd, pos, whence); + if (newpos == (os_off_t) -1) { my_errno=errno; From 76b353d307a3037e52c309169be644b47655ea0e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Oct 2006 18:28:06 -0400 Subject: [PATCH 103/235] Bug#17583: mysql drops connection when stdout is not writable When the client program had its stdout file descriptor closed by the calling shell, after some amount of work (enough to fill a socket buffer) the server would complain about a packet error and then disconnect the client. This is a serious security problem. If stdout is closed before the mysql is exec()d, then the first socket() call allocates file number 1 to communicate with the server. Subsequent write()s to that file number (as when printing results that come back from the database) go back to the server instead in the command channel. So, one should be able to craft data which, upon being selected back from the server to the client, and injected into the command stream become valid MySQL protocol to do something nasty when sent /back/ to the server. The solution is to close explicitly the file descriptor that we *printf() to, so that the libc layer and the OS layer both agree that the file is closed. BitKeeper/etc/collapsed: BitKeeper file /home/cmiller/work/mysql/bug17583/my41-bug17583/BitKeeper/etc/collapsed client/mysql.cc: If standard output is not open (specifically, if dup() of its file number fails) then we explicitly close it so that future uses of the file descriptor behave correctly for a closed file. mysql-test/r/mysql_client.result: Prove that the problem of writing SQL output to the command socket no longer exists. mysql-test/t/mysql_client.test: Prove that the problem of writing SQL output to the command socket no longer exists. --- BitKeeper/etc/collapsed | 1 + client/mysql.cc | 15 +++++++++++++++ mysql-test/r/mysql_client.result | 14 ++++++++++++++ mysql-test/t/mysql_client.test | 19 +++++++++++++++++++ 4 files changed, 49 insertions(+) create mode 100644 BitKeeper/etc/collapsed diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed new file mode 100644 index 00000000000..60be7fa5dc6 --- /dev/null +++ b/BitKeeper/etc/collapsed @@ -0,0 +1 @@ +452a92d0-31-8wSzSfZi165fcGcXPA diff --git a/client/mysql.cc b/client/mysql.cc index f9ca9d4f829..12fa2b56ebf 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -372,6 +372,21 @@ int main(int argc,char *argv[]) else status.add_to_history=1; status.exit_status=1; + + { + /* + The file descriptor-layer may be out-of-sync with the file-number layer, + so we make sure that "stdout" is really open. If its file is closed then + explicitly close the FD layer. + */ + int stdout_fileno_copy; + stdout_fileno_copy= dup(fileno(stdout)); /* Okay if fileno fails. */ + if (stdout_fileno_copy == -1) + fclose(stdout); + else + close(stdout_fileno_copy); /* Clean up dup(). */ + } + load_defaults("my",load_default_groups,&argc,&argv); defaults_argv=argv; if (get_options(argc, (char **) argv)) diff --git a/mysql-test/r/mysql_client.result b/mysql-test/r/mysql_client.result index 87d09428ff6..5375deb250d 100644 --- a/mysql-test/r/mysql_client.result +++ b/mysql-test/r/mysql_client.result @@ -2,3 +2,17 @@ 1 ERROR 1064 (42000) at line 3: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 ERROR at line 1: USE must be followed by a database name +create table t17583 (a int); +insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +select count(*) from t17583; +count(*) +1280 +drop table t17583; +End of 4.1 tests. diff --git a/mysql-test/t/mysql_client.test b/mysql-test/t/mysql_client.test index b382357dacf..2a7f4a935bb 100644 --- a/mysql-test/t/mysql_client.test +++ b/mysql-test/t/mysql_client.test @@ -33,3 +33,22 @@ # --exec echo 'help' | $MYSQL > $MYSQLTEST_VARDIR/tmp/bug20328.tmp --exec echo 'help ' | $MYSQL > $MYSQLTEST_VARDIR/tmp/bug20328.tmp + +# +# Bug#17583: mysql drops connection when stdout is not writable +# +create table t17583 (a int); +insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +# Close to the minimal data needed to exercise bug. +select count(*) from t17583; +--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&- +drop table t17583; + +--echo End of 4.1 tests. From 6c91170e3f90b73298d40286cdb84e47d8d31c8a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Oct 2006 18:50:12 -0400 Subject: [PATCH 104/235] Bug#17583: mysql drops connection when stdout is not writable Porting forward tests to replacement files. mysql-test/r/mysql.result: Ported changes from previous commit to new file. mysql-test/t/mysql.test: Ported changes from previous commit to new file. --- mysql-test/r/mysql.result | 13 +++++++++++++ mysql-test/t/mysql.test | 17 +++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 7dbff4beca5..c8dcafe4a47 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -139,4 +139,17 @@ ERROR at line 1: USE must be followed by a database name \\ '; '; +create table t17583 (a int); +insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +select count(*) from t17583; +count(*) +1280 +drop table t17583; End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 9e3eabf474b..6de18033751 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -147,4 +147,21 @@ drop table t1; --exec echo "SELECT '\';';" >> $MYSQLTEST_VARDIR/tmp/bug20103.sql --exec $MYSQL < $MYSQLTEST_VARDIR/tmp/bug20103.sql 2>&1 +# +# Bug#17583: mysql drops connection when stdout is not writable +# +create table t17583 (a int); +insert into t17583 (a) values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +insert into t17583 select a from t17583; +# Close to the minimal data needed to exercise bug. +select count(*) from t17583; +--exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&- +drop table t17583; + --echo End of 5.0 tests From de443be6b560eae12bb34a1527bddfb62d967340 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 02:36:36 +0400 Subject: [PATCH 105/235] BUG#21524 ps.test updated to meet recent changes in SQL parser mysql-test/r/ps.result: brand new ps.result recorded out of updated ps.test output mysql-test/t/disabled.def: ps.test enabled anew mysql-test/t/ps.test: ps.test updated to ensure FLUSH/RESET are not allowed in stored functions at both parse and execution time --- mysql-test/r/ps.result | 461 ++++++++++++++++++++------------------ mysql-test/t/disabled.def | 1 - mysql-test/t/ps.test | 99 ++++---- 3 files changed, 287 insertions(+), 274 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index b7dae03bf47..9b74703e5b2 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -499,54 +499,6 @@ create temporary table if not exists t1 (a1 int); execute stmt; drop temporary table t1; deallocate prepare stmt; -CREATE TABLE t1( -ID int(10) unsigned NOT NULL auto_increment, -Member_ID varchar(15) NOT NULL default '', -Action varchar(12) NOT NULL, -Action_Date datetime NOT NULL, -Track varchar(15) default NULL, -User varchar(12) default NULL, -Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update -CURRENT_TIMESTAMP, -PRIMARY KEY (ID), -KEY Action (Action), -KEY Action_Date (Action_Date) -); -INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES -('111111', 'Disenrolled', '2006-03-01', 'CAD' ), -('111111', 'Enrolled', '2006-03-01', 'CAD' ), -('111111', 'Disenrolled', '2006-07-03', 'CAD' ), -('222222', 'Enrolled', '2006-03-07', 'CAD' ), -('222222', 'Enrolled', '2006-03-07', 'CHF' ), -('222222', 'Disenrolled', '2006-08-02', 'CHF' ), -('333333', 'Enrolled', '2006-03-01', 'CAD' ), -('333333', 'Disenrolled', '2006-03-01', 'CAD' ), -('444444', 'Enrolled', '2006-03-01', 'CAD' ), -('555555', 'Disenrolled', '2006-03-01', 'CAD' ), -('555555', 'Enrolled', '2006-07-21', 'CAD' ), -('555555', 'Disenrolled', '2006-03-01', 'CHF' ), -('666666', 'Enrolled', '2006-02-09', 'CAD' ), -('666666', 'Enrolled', '2006-05-12', 'CHF' ), -('666666', 'Disenrolled', '2006-06-01', 'CAD' ); -PREPARE STMT FROM -"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 - WHERE Member_ID=? AND Action='Enrolled' AND - (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 - WHERE Member_ID=? - GROUP BY Track - HAVING Track>='CAD' AND - MAX(Action_Date)>'2006-03-01')"; -SET @id='111111'; -EXECUTE STMT USING @id,@id; -GROUP_CONCAT(Track SEPARATOR ', ') -NULL -SET @id='222222'; -EXECUTE STMT USING @id,@id; -GROUP_CONCAT(Track SEPARATOR ', ') -CAD -DEALLOCATE PREPARE STMT; -DROP TABLE t1; -End of 4.1 tests create table t1 (a varchar(20)); insert into t1 values ('foo'); prepare stmt FROM 'SELECT char_length (a) FROM t1'; @@ -564,77 +516,6 @@ SELECT FOUND_ROWS(); FOUND_ROWS() 2 deallocate prepare stmt; -create table t1 (a char(3) not null, b char(3) not null, -c char(3) not null, primary key (a, b, c)); -create table t2 like t1; -prepare stmt from -"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) - where t1.a=1"; -execute stmt; -a -execute stmt; -a -execute stmt; -a -prepare stmt from -"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from -(t1 left outer join t2 on t2.a=? and t1.b=t2.b) -left outer join t2 t3 on t3.a=? where t1.a=?"; -set @a:=1, @b:=1, @c:=1; -execute stmt using @a, @b, @c; -a b c a b c -execute stmt using @a, @b, @c; -a b c a b c -execute stmt using @a, @b, @c; -a b c a b c -deallocate prepare stmt; -drop table t1,t2; -SET @aux= "SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS A, - INFORMATION_SCHEMA.COLUMNS B - WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA - AND A.TABLE_NAME = B.TABLE_NAME - AND A.COLUMN_NAME = B.COLUMN_NAME AND - A.TABLE_NAME = 'user'"; -prepare my_stmt from @aux; -execute my_stmt; -COUNT(*) -39 -execute my_stmt; -COUNT(*) -39 -execute my_stmt; -COUNT(*) -39 -deallocate prepare my_stmt; -drop procedure if exists p1| -drop table if exists t1| -create table t1 (id int)| -insert into t1 values(1)| -create procedure p1(a int, b int) -begin -declare c int; -select max(id)+1 into c from t1; -insert into t1 select a+b; -insert into t1 select a-b; -insert into t1 select a-c; -end| -set @a= 3, @b= 4| -prepare stmt from "call p1(?, ?)"| -execute stmt using @a, @b| -execute stmt using @a, @b| -select * from t1| -id -1 -7 --1 -1 -7 --1 --5 -deallocate prepare stmt| -drop procedure p1| -drop table t1| drop table if exists t1; Warnings: Note 1051 Unknown table 't1' @@ -698,47 +579,6 @@ id 3 deallocate prepare stmt; drop table t1, t2; -create table t1 (a int); -insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -prepare stmt from "select * from t1 limit ?, ?"; -set @offset=0, @limit=1; -execute stmt using @offset, @limit; -a -1 -select * from t1 limit 0, 1; -a -1 -set @offset=3, @limit=2; -execute stmt using @offset, @limit; -a -4 -5 -select * from t1 limit 3, 2; -a -4 -5 -prepare stmt from "select * from t1 limit ?"; -execute stmt using @limit; -a -1 -2 -prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; -ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' -prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; -set @offset=9; -set @limit=2; -execute stmt using @offset, @limit; -a -10 -1 -prepare stmt from "(select * from t1 limit ?, ?) union all - (select * from t1 limit ?, ?) order by a limit ?"; -execute stmt using @offset, @limit, @offset, @limit, @limit; -a -10 -10 -drop table t1; -deallocate prepare stmt; create table t1 (id int); prepare stmt from "insert into t1 (id) select id from t1 union select id from t1"; execute stmt; @@ -839,15 +679,6 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp select ? from t1; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? from t1' at line 1 drop table t1; -CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; -CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; -CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; -PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; -EXECUTE b12651; -1 -DROP VIEW b12651_V1; -DROP TABLE b12651_T1, b12651_T2; -DEALLOCATE PREPARE b12651; prepare stmt from "select @@time_zone"; execute stmt; @@time_zone @@ -1064,6 +895,194 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count; @@max_prepared_stmt_count @@prepared_stmt_count 3 0 set global max_prepared_stmt_count= @old_max_prepared_stmt_count; +drop table if exists t1; +create temporary table if not exists t1 (a1 int); +prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1"; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +deallocate prepare stmt; +CREATE TABLE t1( +ID int(10) unsigned NOT NULL auto_increment, +Member_ID varchar(15) NOT NULL default '', +Action varchar(12) NOT NULL, +Action_Date datetime NOT NULL, +Track varchar(15) default NULL, +User varchar(12) default NULL, +Date_Updated timestamp NOT NULL default CURRENT_TIMESTAMP on update +CURRENT_TIMESTAMP, +PRIMARY KEY (ID), +KEY Action (Action), +KEY Action_Date (Action_Date) +); +INSERT INTO t1(Member_ID, Action, Action_Date, Track) VALUES +('111111', 'Disenrolled', '2006-03-01', 'CAD' ), +('111111', 'Enrolled', '2006-03-01', 'CAD' ), +('111111', 'Disenrolled', '2006-07-03', 'CAD' ), +('222222', 'Enrolled', '2006-03-07', 'CAD' ), +('222222', 'Enrolled', '2006-03-07', 'CHF' ), +('222222', 'Disenrolled', '2006-08-02', 'CHF' ), +('333333', 'Enrolled', '2006-03-01', 'CAD' ), +('333333', 'Disenrolled', '2006-03-01', 'CAD' ), +('444444', 'Enrolled', '2006-03-01', 'CAD' ), +('555555', 'Disenrolled', '2006-03-01', 'CAD' ), +('555555', 'Enrolled', '2006-07-21', 'CAD' ), +('555555', 'Disenrolled', '2006-03-01', 'CHF' ), +('666666', 'Enrolled', '2006-02-09', 'CAD' ), +('666666', 'Enrolled', '2006-05-12', 'CHF' ), +('666666', 'Disenrolled', '2006-06-01', 'CAD' ); +PREPARE STMT FROM +"SELECT GROUP_CONCAT(Track SEPARATOR ', ') FROM t1 + WHERE Member_ID=? AND Action='Enrolled' AND + (Track,Action_Date) IN (SELECT Track, MAX(Action_Date) FROM t1 + WHERE Member_ID=? + GROUP BY Track + HAVING Track>='CAD' AND + MAX(Action_Date)>'2006-03-01')"; +SET @id='111111'; +EXECUTE STMT USING @id,@id; +GROUP_CONCAT(Track SEPARATOR ', ') +NULL +SET @id='222222'; +EXECUTE STMT USING @id,@id; +GROUP_CONCAT(Track SEPARATOR ', ') +CAD +DEALLOCATE PREPARE STMT; +DROP TABLE t1; +End of 4.1 tests +create table t1 (a varchar(20)); +insert into t1 values ('foo'); +prepare stmt FROM 'SELECT char_length (a) FROM t1'; +ERROR 42000: FUNCTION test.char_length does not exist +drop table t1; +create table t1 (a char(3) not null, b char(3) not null, +c char(3) not null, primary key (a, b, c)); +create table t2 like t1; +prepare stmt from +"select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) + where t1.a=1"; +execute stmt; +a +execute stmt; +a +execute stmt; +a +prepare stmt from +"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from +(t1 left outer join t2 on t2.a=? and t1.b=t2.b) +left outer join t2 t3 on t3.a=? where t1.a=?"; +set @a:=1, @b:=1, @c:=1; +execute stmt using @a, @b, @c; +a b c a b c +execute stmt using @a, @b, @c; +a b c a b c +execute stmt using @a, @b, @c; +a b c a b c +deallocate prepare stmt; +drop table t1,t2; +SET @aux= "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS A, + INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME + AND A.COLUMN_NAME = B.COLUMN_NAME AND + A.TABLE_NAME = 'user'"; +prepare my_stmt from @aux; +execute my_stmt; +COUNT(*) +39 +execute my_stmt; +COUNT(*) +39 +execute my_stmt; +COUNT(*) +39 +deallocate prepare my_stmt; +drop procedure if exists p1| +drop table if exists t1| +create table t1 (id int)| +insert into t1 values(1)| +create procedure p1(a int, b int) +begin +declare c int; +select max(id)+1 into c from t1; +insert into t1 select a+b; +insert into t1 select a-b; +insert into t1 select a-c; +end| +set @a= 3, @b= 4| +prepare stmt from "call p1(?, ?)"| +execute stmt using @a, @b| +execute stmt using @a, @b| +select * from t1| +id +1 +7 +-1 +1 +7 +-1 +-5 +deallocate prepare stmt| +drop procedure p1| +drop table t1| +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +prepare stmt from "select * from t1 limit ?, ?"; +set @offset=0, @limit=1; +execute stmt using @offset, @limit; +a +1 +select * from t1 limit 0, 1; +a +1 +set @offset=3, @limit=2; +execute stmt using @offset, @limit; +a +4 +5 +select * from t1 limit 3, 2; +a +4 +5 +prepare stmt from "select * from t1 limit ?"; +execute stmt using @limit; +a +1 +2 +prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; +ERROR 42000: This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery' +prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; +set @offset=9; +set @limit=2; +execute stmt using @offset, @limit; +a +10 +1 +prepare stmt from "(select * from t1 limit ?, ?) union all + (select * from t1 limit ?, ?) order by a limit ?"; +execute stmt using @offset, @limit, @offset, @limit, @limit; +a +10 +10 +drop table t1; +deallocate prepare stmt; +CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; +CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; +CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; +PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; +EXECUTE b12651; +1 +DROP VIEW b12651_V1; +DROP TABLE b12651_T1, b12651_T2; +DEALLOCATE PREPARE b12651; create table t1 (id int); prepare ins_call from "insert into t1 (id) values (1)"; execute ins_call; @@ -1365,22 +1384,26 @@ create procedure proc_1() reset query cache; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin reset query cache; return 1; end| +ERROR 0A000: RESET is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 0A000: FLUSH is not allowed in stored function or trigger +ERROR 0A000: RESET is not allowed in stored function or trigger drop function func_1; +drop procedure proc_1; prepare abc from "reset query cache"; execute abc; execute abc; execute abc; deallocate prepare abc; create procedure proc_1() reset master; -drop procedure proc_1; create function func_1() returns int begin reset master; return 1; end| +ERROR 0A000: RESET is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 0A000: FLUSH is not allowed in stored function or trigger +ERROR 0A000: RESET is not allowed in stored function or trigger drop function func_1; +drop procedure proc_1; prepare abc from "reset master"; execute abc; execute abc; @@ -1390,11 +1413,13 @@ create procedure proc_1() reset slave; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin reset slave; return 1; end| +ERROR 0A000: RESET is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 0A000: FLUSH is not allowed in stored function or trigger +ERROR 0A000: RESET is not allowed in stored function or trigger drop function func_1; +drop procedure proc_1; prepare abc from "reset slave"; execute abc; execute abc; @@ -1429,13 +1454,13 @@ call proc_1(); call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush hosts; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush hosts"; execute abc; execute abc; @@ -1445,13 +1470,13 @@ create procedure proc_1() flush privileges; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush privileges; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush privileges"; deallocate prepare abc; create procedure proc_1() flush tables with read lock; @@ -1461,9 +1486,13 @@ call proc_1(); unlock tables; call proc_1(); unlock tables; -drop procedure proc_1; create function func_1() returns int begin flush tables with read lock; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| +select func_1(), func_1(), func_1() from dual; +ERROR 0A000: FLUSH is not allowed in stored function or trigger +drop function func_1; +drop procedure proc_1; prepare abc from "flush tables with read lock"; execute abc; execute abc; @@ -1474,13 +1503,13 @@ create procedure proc_1() flush tables; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush tables; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush tables"; execute abc; execute abc; @@ -1540,13 +1569,13 @@ mysql user 0 0 mysql general_log 1 0 mysql host 0 0 flush tables; -drop procedure proc_1; create function func_1() returns int begin flush tables; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; flush tables; select Host, User from mysql.user limit 0; Host User @@ -1603,13 +1632,13 @@ create procedure proc_1() flush logs; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush logs; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush logs"; execute abc; execute abc; @@ -1619,13 +1648,13 @@ create procedure proc_1() flush status; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush status; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush status"; execute abc; execute abc; @@ -1635,39 +1664,39 @@ create procedure proc_1() flush slave; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush slave; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush slave"; execute abc; execute abc; execute abc; deallocate prepare abc; create procedure proc_1() flush master; -drop procedure proc_1; create function func_1() returns int begin flush master; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush master"; deallocate prepare abc; create procedure proc_1() flush des_key_file; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush des_key_file; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush des_key_file"; execute abc; execute abc; @@ -1677,13 +1706,13 @@ create procedure proc_1() flush user_resources; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; create function func_1() returns int begin flush user_resources; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger +create function func_1() returns int begin call proc_1(); return 1; end| select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist +ERROR 0A000: FLUSH is not allowed in stored function or trigger drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist +drop procedure proc_1; prepare abc from "flush user_resources"; execute abc; execute abc; @@ -1763,18 +1792,6 @@ Db Name Definer Type Execute at Interval value Interval field Starts Ends Status execute abc; Db Name Definer Type Execute at Interval value Interval field Starts Ends Status deallocate prepare abc; -create procedure proc_1() show scheduler status; -drop procedure proc_1; -create function func_1() returns int begin show scheduler status; return 1; end| -ERROR 0A000: Not allowed to return a result set from a function -select func_1(), func_1(), func_1() from dual; -ERROR 42000: FUNCTION test.func_1 does not exist -drop function func_1; -ERROR 42000: FUNCTION test.func_1 does not exist -prepare abc from "show scheduler status"; -ERROR HY000: This command is not supported in the prepared statement protocol yet -deallocate prepare abc; -ERROR HY000: Unknown prepared statement handler (abc) given to DEALLOCATE PREPARE drop procedure if exists a; create procedure a() select 42; create procedure proc_1(a char(2)) show create procedure a; @@ -1952,11 +1969,11 @@ ERROR HY000: No paths allowed for shared library drop procedure proc_1; create procedure proc_1() install plugin my_plug soname 'some_plugin.so'; call proc_1(); -ERROR HY000: Can't open shared library '/work/mysql-5.1-runtime/mysql-test/lib/mysql/some_plugin.so' (errno: 0 cannot open shared object file: No such file or directory) +ERROR HY000: Can't open shared library PATH_TO_SO (errno: 0 cannot open shared object file: No such file or directory) call proc_1(); -ERROR HY000: Can't open shared library '/work/mysql-5.1-runtime/mysql-test/lib/mysql/some_plugin.so' (errno: 22 cannot open shared object file: No such file or directory) +ERROR HY000: Can't open shared library PATH_TO_SO (errno: 22 cannot open shared object file: No such file or directory) call proc_1(); -ERROR HY000: Can't open shared library '/work/mysql-5.1-runtime/mysql-test/lib/mysql/some_plugin.so' (errno: 22 cannot open shared object file: No such file or directory) +ERROR HY000: Can't open shared library PATH_TO_SO (errno: 22 cannot open shared object file: No such file or directory) drop procedure proc_1; create function func_1() returns int begin install plugin my_plug soname '/tmp/plugin'; return 1; end| ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. @@ -2086,7 +2103,7 @@ drop user pstest_xyz@localhost; deallocate prepare abc; drop event if exists xyz; create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end| -ERROR 0A000: Not allowed to return a result set from a function +ERROR HY000: Recursivity of EVENT DDL statements is forbidden when body is present select func_1(), func_1(), func_1() from dual; ERROR 42000: FUNCTION test.func_1 does not exist drop function func_1; diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 1c2503e3240..6af71e32cc4 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -15,7 +15,6 @@ ndb_autodiscover : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t ndb_autodiscover2 : BUG#18952 2006-02-16 jmiller Needs to be fixed w.r.t binlog ndb_load : BUG#17233 2006-05-04 tomas failed load data from infile causes mysqld dbug_assert, binlog not flushed partition_03ndb : BUG#16385 2006-03-24 mikael Partitions: crash when updating a range partitioned NDB table -ps : BUG#21524 2006-08-08 pgalbraith 'ps' test fails in --ps-protocol test AMD64 bit ps_7ndb : BUG#18950 2006-02-16 jmiller create table like does not obtain LOCK_open rpl_ndb_2innodb : BUG#19227 2006-04-20 pekka pk delete apparently not replicated rpl_ndb_2myisam : BUG#19227 Seems to pass currently diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 31034099515..67efa593942 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1447,13 +1447,15 @@ create procedure proc_1() reset query cache; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin reset query cache; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; drop function func_1; +drop procedure proc_1; prepare abc from "reset query cache"; execute abc; execute abc; @@ -1462,13 +1464,15 @@ deallocate prepare abc; create procedure proc_1() reset master; -drop procedure proc_1; delimiter |; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin reset master; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; drop function func_1; +drop procedure proc_1; prepare abc from "reset master"; execute abc; execute abc; @@ -1480,13 +1484,15 @@ create procedure proc_1() reset slave; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin reset slave; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; drop function func_1; +drop procedure proc_1; prepare abc from "reset slave"; execute abc; execute abc; @@ -1527,15 +1533,15 @@ call proc_1(); call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush hosts; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush hosts"; execute abc; execute abc; @@ -1547,15 +1553,15 @@ create procedure proc_1() flush privileges; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush privileges; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush privileges"; deallocate prepare abc; @@ -1567,11 +1573,15 @@ call proc_1(); unlock tables; call proc_1(); unlock tables; -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush tables with read lock; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG +select func_1(), func_1(), func_1() from dual; +drop function func_1; +drop procedure proc_1; prepare abc from "flush tables with read lock"; execute abc; execute abc; @@ -1584,15 +1594,15 @@ create procedure proc_1() flush tables; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush tables; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush tables"; execute abc; execute abc; @@ -1622,15 +1632,15 @@ select Host, User from mysql.user limit 0; select Host, Db from mysql.host limit 0; show open tables from mysql; flush tables; -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush tables; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; flush tables; select Host, User from mysql.user limit 0; select Host, Db from mysql.host limit 0; @@ -1659,15 +1669,15 @@ create procedure proc_1() flush logs; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush logs; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush logs"; execute abc; execute abc; @@ -1679,15 +1689,15 @@ create procedure proc_1() flush status; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush status; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush status"; execute abc; execute abc; @@ -1699,15 +1709,15 @@ create procedure proc_1() flush slave; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush slave; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush slave"; execute abc; execute abc; @@ -1716,15 +1726,15 @@ deallocate prepare abc; create procedure proc_1() flush master; -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush master; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush master"; deallocate prepare abc; @@ -1733,15 +1743,15 @@ create procedure proc_1() flush des_key_file; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush des_key_file; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush des_key_file"; execute abc; execute abc; @@ -1753,15 +1763,15 @@ create procedure proc_1() flush user_resources; call proc_1(); call proc_1(); call proc_1(); -drop procedure proc_1; delimiter |; --error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG create function func_1() returns int begin flush user_resources; return 1; end| +create function func_1() returns int begin call proc_1(); return 1; end| delimiter ;| ---error ER_SP_DOES_NOT_EXIST +--error ER_STMT_NOT_ALLOWED_IN_SF_OR_TRG select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST drop function func_1; +drop procedure proc_1; prepare abc from "flush user_resources"; execute abc; execute abc; @@ -1865,22 +1875,6 @@ execute abc; deallocate prepare abc; -create procedure proc_1() show scheduler status; -drop procedure proc_1; -delimiter |; ---error ER_SP_NO_RETSET -create function func_1() returns int begin show scheduler status; return 1; end| -delimiter ;| ---error ER_SP_DOES_NOT_EXIST -select func_1(), func_1(), func_1() from dual; ---error ER_SP_DOES_NOT_EXIST -drop function func_1; ---error ER_UNSUPPORTED_PS -prepare abc from "show scheduler status"; ---error ER_UNKNOWN_STMT_HANDLER -deallocate prepare abc; - - --disable_warnings drop procedure if exists a; --enable_warnings @@ -1997,10 +1991,13 @@ call proc_1(); call proc_1(); drop procedure proc_1; create procedure proc_1() install plugin my_plug soname 'some_plugin.so'; +--replace_regex / \'.*\'/ PATH_TO_SO/ --error ER_CANT_OPEN_LIBRARY call proc_1(); +--replace_regex / \'.*\'/ PATH_TO_SO/ --error ER_CANT_OPEN_LIBRARY call proc_1(); +--replace_regex / \'.*\'/ PATH_TO_SO/ --error ER_CANT_OPEN_LIBRARY call proc_1(); drop procedure proc_1; @@ -2150,7 +2147,7 @@ drop event if exists xyz; #drop event xyz; #drop procedure proc_1; delimiter |; ---error ER_SP_NO_RETSET +--error ER_EVENT_RECURSIVITY_FORBIDDEN create function func_1() returns int begin create event xyz on schedule at now() do select 123; return 1; end| delimiter ;| --error ER_SP_DOES_NOT_EXIST From 46a3e809fc38acb1d1d9cacaa4a752f4644d8172 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 07:08:32 +0400 Subject: [PATCH 106/235] BUG#21524 ER_CANT_OPEN_LIBRARY output message used to confuse mysqltest on Solaris. Varying part of the message is now suppressed mysql-test/r/ps.result: ps.result updated mysql-test/t/ps.test: The error code and the additional output grepped out of ER_CANT_OPEN_LIBRARY message due to the output varies across different platforms --- mysql-test/r/ps.result | 6 +++--- mysql-test/t/ps.test | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 9b74703e5b2..f7a9f0440a3 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1969,11 +1969,11 @@ ERROR HY000: No paths allowed for shared library drop procedure proc_1; create procedure proc_1() install plugin my_plug soname 'some_plugin.so'; call proc_1(); -ERROR HY000: Can't open shared library PATH_TO_SO (errno: 0 cannot open shared object file: No such file or directory) +ERROR HY000: Can't open shared library call proc_1(); -ERROR HY000: Can't open shared library PATH_TO_SO (errno: 22 cannot open shared object file: No such file or directory) +ERROR HY000: Can't open shared library call proc_1(); -ERROR HY000: Can't open shared library PATH_TO_SO (errno: 22 cannot open shared object file: No such file or directory) +ERROR HY000: Can't open shared library drop procedure proc_1; create function func_1() returns int begin install plugin my_plug soname '/tmp/plugin'; return 1; end| ERROR HY000: Explicit or implicit commit is not allowed in stored function or trigger. diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 67efa593942..902d8fcd9d8 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1991,13 +1991,13 @@ call proc_1(); call proc_1(); drop procedure proc_1; create procedure proc_1() install plugin my_plug soname 'some_plugin.so'; ---replace_regex / \'.*\'/ PATH_TO_SO/ +--replace_regex /(Can\'t open shared library).*$/\1/ --error ER_CANT_OPEN_LIBRARY call proc_1(); ---replace_regex / \'.*\'/ PATH_TO_SO/ +--replace_regex /(Can\'t open shared library).*$/\1/ --error ER_CANT_OPEN_LIBRARY call proc_1(); ---replace_regex / \'.*\'/ PATH_TO_SO/ +--replace_regex /(Can\'t open shared library).*$/\1/ --error ER_CANT_OPEN_LIBRARY call proc_1(); drop procedure proc_1; From da0b4e97430fb4c49bf1a934c893e7d3e3351e02 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 00:03:21 -0600 Subject: [PATCH 107/235] Fix some bad code in mysqltest.c and mysql-test-run.pl which could cause segfault / wrong LD_LIBRARY_PATH settings. client/mysqltest.c: Remove vsnprintf() and DBUG_PRINT from die() function, as it's not portable to Windows, and it's not allowed to call vsnprintf() and then vfprintf() with the same args. Can't just print the buffer here, because the buffer is a fixed size. If the message is longer than will fit int he buffer, it would get truncated on Unix, and the full thing would be printed on Windows. This DBUG_PRINT isn't important enough for this hassle, so just get rid of it. mysql-test/mysql-test-run.pl: Remove bogus quoting of $ENV{LD_LIBRARY_PATH} and $ENV{DYLD_LIBRARY_PATH} in environment_setup(). --- client/mysqltest.c | 7 ------- mysql-test/mysql-test-run.pl | 4 ++-- 2 files changed, 2 insertions(+), 9 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3f8bc99bdf8..0a9549acc47 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -727,13 +727,6 @@ void die(const char *fmt, ...) va_start(args, fmt); if (fmt) { -#ifdef DBUG_ON -#ifndef __WIN__ - char buff[256]; - vsnprintf(buff, sizeof(buff), fmt, args); - DBUG_PRINT("error", ("%s", buff)); -#endif -#endif fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) fprintf(stderr, "In included file \"%s\": ", diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7b9a55053f0..6427e977da5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1505,11 +1505,11 @@ sub environment_setup () { } $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', qw($ENV{'LD_LIBRARY_PATH'}))); + split(':', $ENV{'LD_LIBRARY_PATH'})); mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}"); $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', qw($ENV{'DYLD_LIBRARY_PATH'}))); + split(':', $ENV{'DYLD_LIBRARY_PATH'})); mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}"); From c247bf9dc3c370c70dc763dcf361c85ee20035fd Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 10:17:39 +0200 Subject: [PATCH 108/235] BUG#21811 Odd casting with date + INTERVAL arithmetic - Type casting was not consequent, thus when adding a DATE type with a WEEK interval the result tpe was DATETIME and not DATE as is the norm. - By changing the order of the date type enumerations the type casting bug is resolved. To comply with the new order the array interval_type_to_name needed to change accordingly. include/my_time.h: Changed enumeration order to make week interval appear in a more logical order. This affects type casting when a date is added to an interval. sql/time.cc: Moved string WEEK to match enumeration in interval_type --- include/my_time.h | 20 +++++++++++++++----- sql/time.cc | 13 ++++++++++++- 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/include/my_time.h b/include/my_time.h index 3025b98a9c4..3e659630689 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -92,15 +92,25 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to); int my_datetime_to_str(const MYSQL_TIME *l_time, char *to); int my_TIME_to_str(const MYSQL_TIME *l_time, char *to); -/* - The following must be sorted so that simple intervals comes first. - (get_interval_value() depends on this) +/* + Available interval types used in any statement. + + 'interval_type' must be sorted so that simple intervals comes first, + ie year, quarter, month, week, day, hour, etc. The order based on + interval size is also important and the intervals should be kept in a + large to smaller order. (get_interval_value() depends on this) + + Note: If you change the order of elements in this enum you should fix + order of elements in 'interval_type_to_name' and 'interval_names' + arrays + + See also interval_type_to_name, get_interval_value, interval_names */ enum interval_type { - INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_DAY, INTERVAL_HOUR, - INTERVAL_MINUTE, INTERVAL_WEEK, INTERVAL_SECOND, INTERVAL_MICROSECOND , + INTERVAL_YEAR, INTERVAL_QUARTER, INTERVAL_MONTH, INTERVAL_WEEK, INTERVAL_DAY, + INTERVAL_HOUR, INTERVAL_MINUTE, INTERVAL_SECOND, INTERVAL_MICROSECOND, INTERVAL_YEAR_MONTH, INTERVAL_DAY_HOUR, INTERVAL_DAY_MINUTE, INTERVAL_DAY_SECOND, INTERVAL_HOUR_MINUTE, INTERVAL_HOUR_SECOND, INTERVAL_MINUTE_SECOND, INTERVAL_DAY_MICROSECOND, INTERVAL_HOUR_MICROSECOND, diff --git a/sql/time.cc b/sql/time.cc index 0461f7723c6..467dbc684a5 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -25,14 +25,25 @@ #ifndef TESTTIME +/* + Name description of interval names used in statements. + + 'interval_type_to_name' is ordered and sorted on interval size and + interval complexity. + Order of elements in 'interval_type_to_name' should correspond to + the order of elements in 'interval_type' enum + + See also interval_type, interval_names +*/ + LEX_STRING interval_type_to_name[INTERVAL_LAST] = { { C_STRING_WITH_LEN("YEAR")}, { C_STRING_WITH_LEN("QUARTER")}, { C_STRING_WITH_LEN("MONTH")}, + { C_STRING_WITH_LEN("WEEK")}, { C_STRING_WITH_LEN("DAY")}, { C_STRING_WITH_LEN("HOUR")}, { C_STRING_WITH_LEN("MINUTE")}, - { C_STRING_WITH_LEN("WEEK")}, { C_STRING_WITH_LEN("SECOND")}, { C_STRING_WITH_LEN("MICROSECOND")}, { C_STRING_WITH_LEN("YEAR_MONTH")}, From ca126a2bbdf50736d2cb1909be1bde8808ba2d6c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 12:44:03 +0400 Subject: [PATCH 109/235] Fix for bug #22728 "Handler_rollback value is growing". The bug is present only in 4.1, will be null-merged to 5.0 For InnoDB, check value of thd->transaction.all.innodb_active_trans instead of thd->transaction.stmt.innobase_tid to see if we really need to rollback. mysql-test/r/innodb_mysql.result: Added testcase for bug #22728 "Handler_rollback value is growing" mysql-test/t/innodb_mysql.test: Added testcase for bug #22728 "Handler_rollback value is growing" sql/handler.cc: For InnoDB, check value of thd->transaction.all.innodb_active_trans instead of thd->transaction.stmt.innobase_tid to see if we really need to rollback. --- mysql-test/r/innodb_mysql.result | 10 ++++++++++ mysql-test/t/innodb_mysql.test | 18 ++++++++++++++++++ sql/handler.cc | 2 +- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index 2a4e3555e3b..d1f34e681e9 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -54,3 +54,13 @@ c.c_id = 218 and expiredate is null; slai_id 12 drop table t1, t2; +flush status; +create table t1 (c1 int) engine=innodb; +handler t1 open; +handler t1 read first; +c1 +show /*!50002 GLOBAL */ status like 'Handler_rollback'; +Variable_name Value +Handler_rollback 0 +drop table t1; +End of 4.1 tests diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index f31e4d64789..ce8030d389d 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -57,3 +57,21 @@ where c.c_id = 218 and expiredate is null; drop table t1, t2; + +# +# Bug #22728 - Handler_rollback value is growing +# +flush status; +create table t1 (c1 int) engine=innodb; +connect (con1,localhost,root,,); +connect (con2,localhost,root,,); +connection con2; +handler t1 open; +handler t1 read first; +disconnect con2; +connection con1; +show /*!50002 GLOBAL */ status like 'Handler_rollback'; +connection default; +drop table t1; +disconnect con1; +--echo End of 4.1 tests diff --git a/sql/handler.cc b/sql/handler.cc index e166f9885fc..7dc72938f7a 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -648,7 +648,7 @@ int ha_rollback_trans(THD *thd, THD_TRANS *trans) } #endif #ifdef HAVE_INNOBASE_DB - if (trans->innobase_tid) + if (thd->transaction.all.innodb_active_trans) { if ((error=innobase_rollback(thd, trans->innobase_tid))) { From a4a319cf0c266aadac0442a7c55dcef2529f8abc Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 11:07:25 +0200 Subject: [PATCH 110/235] Fix a typo regarding checking whether HA_VAR_LENGTH_KEY is set. This has always worked because when flag is !=0 then HA_VAR_LENGTH_KEY is always set. Therefore, a test case cannot reveal a faulty behavior. Fix for bug#23074: typo in myisam/sort.c myisam/sort.c: fix typo. Nevertheless, it has worked as expected because when a bit in flag is set HA_VAR_LENGTH_KEY has been always set too. Actually, no problem exposed through DDL. --- myisam/sort.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/myisam/sort.c b/myisam/sort.c index 1a3dc147cd9..364d860272c 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -324,7 +324,7 @@ pthread_handler_decl(thr_find_all_keys,arg) if (info->sort_info->got_error) goto err; - if (info->keyinfo->flag && HA_VAR_LENGTH_KEY) + if (info->keyinfo->flag & HA_VAR_LENGTH_KEY) { info->write_keys=write_keys_varlen; info->read_to_buffer=read_to_buffer_varlen; @@ -513,7 +513,7 @@ int thr_write_keys(MI_SORT_PARAM *sort_param) { if (got_error) continue; - if (sinfo->keyinfo->flag && HA_VAR_LENGTH_KEY) + if (sinfo->keyinfo->flag & HA_VAR_LENGTH_KEY) { sinfo->write_keys=write_keys_varlen; sinfo->read_to_buffer=read_to_buffer_varlen; From 3caef95e641b335b5fb0fcbaec79ec97d868c816 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 11:21:44 +0200 Subject: [PATCH 111/235] Fix some bad code in mysqltest.c which cause segfault client/mysqltest.c: Remove vsnprintf() and DBUG_PRINT from die() function, as it's not portable to Windows, and it's not allowed to call vsnprintf() and then vfprintf() with the same args. Can't just print the buffer here, because the buffer is a fixed size. If the message is longer than will fit int he buffer, it would get truncated on Unix, and the full thing would be printed on Windows. This DBUG_PRINT isn't important enough for this hassle, so just get rid of it. --- client/mysqltest.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 3f8bc99bdf8..0a9549acc47 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -727,13 +727,6 @@ void die(const char *fmt, ...) va_start(args, fmt); if (fmt) { -#ifdef DBUG_ON -#ifndef __WIN__ - char buff[256]; - vsnprintf(buff, sizeof(buff), fmt, args); - DBUG_PRINT("error", ("%s", buff)); -#endif -#endif fprintf(stderr, "mysqltest: "); if (cur_file && cur_file != file_stack) fprintf(stderr, "In included file \"%s\": ", From 18b91b023d5145cc900a503b168414abd11f3650 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 13:42:48 +0200 Subject: [PATCH 112/235] Cset exclude: Kristofer.Pettersson@naruto.|ChangeSet|20060922092201|15946 sql/item_timefunc.cc: Exclude --- sql/item_timefunc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 0b65fdafe31..02c8ab19354 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1876,7 +1876,7 @@ void Item_date_add_interval::fix_length_and_dec() cached_field_type= MYSQL_TYPE_DATETIME; else if (arg0_field_type == MYSQL_TYPE_DATE) { - if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH || int_type == INTERVAL_WEEK ) + if (int_type <= INTERVAL_DAY || int_type == INTERVAL_YEAR_MONTH) cached_field_type= arg0_field_type; else cached_field_type= MYSQL_TYPE_DATETIME; From a0081378801c21915e94ca25a16213843d42599f Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 14:50:19 +0200 Subject: [PATCH 113/235] Improve restart logic all code to detect restart is now in the functions 'run_testcase_need_master/slave_restart' Remove the faulty qw Only look for mysql_fix_privilege_tables if not windows mysql-test/lib/mtr_cases.pl: Move all code to determine when to restart into 'run_testcase_need_master/slave_restart' Add possibility to wite --force-restart in -master.opt file, this will force a restart and since master is not started with any special options there is no need to restart again afterwards. mysql-test/mysql-test-run.pl: Remove the qw surrounding ENV{'LD_LIBRARY_PATH'} Only look for the sh script mysql_fix_privileges when not on windows Remove warnings about using unitialized variables Improve the restart logic, eall code to determine when to restart is now in run_testcase_need_master_restart and run_testcase_need_slave_restart mysql-test/t/bdb-alter-table-2-master.opt: Use --force-restart mysql-test/t/not_embedded_server-master.opt: Use --force-restart --- mysql-test/lib/mtr_cases.pl | 109 +++++++------- mysql-test/mysql-test-run.pl | 148 +++++++++----------- mysql-test/t/bdb-alter-table-2-master.opt | 2 +- mysql-test/t/not_embedded_server-master.opt | 2 +- 4 files changed, 119 insertions(+), 142 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 435ea73e8a3..e6980a0abb9 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -152,9 +152,7 @@ sub collect_test_cases ($) { closedir TESTDIR; } - # To speed things up, we sort first in if the test require a restart - # or not, second in alphanumeric order. - + # Reorder the test cases in an order that wil make them faster to run if ( $::opt_reorder ) { @@ -207,7 +205,6 @@ sub collect_test_cases ($) { # Append the criteria for sorting, in order of importance. # push(@criteria, "ndb=" . ($tinfo->{'ndb_test'} ? "1" : "0")); - push(@criteria, "restart=" . ($tinfo->{'master_restart'} ? "1" : "0")); # Group test with equal options together. # Ending with "~" makes empty sort later than filled push(@criteria, join("!", sort @{$tinfo->{'master_opt'}}) . "~"); @@ -313,13 +310,6 @@ sub collect_one_test_case($$$$$$$) { { # This is an ndb test or all tests should be run with ndb cluster started $tinfo->{'ndb_test'}= 1; - if ( $::opt_skip_ndbcluster ) - { - # All ndb test's should be skipped - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster test(--skip-ndbcluster)"; - return; - } if ( ! $::opt_ndbcluster_supported ) { # Ndb is not supported, skip them @@ -327,6 +317,13 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'comment'}= "No ndbcluster support"; return; } + elsif ( $::opt_skip_ndbcluster ) + { + # All ndb test's should be skipped + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)"; + return; + } } else { @@ -357,52 +354,58 @@ sub collect_one_test_case($$$$$$$) { if ( -f $master_opt_file ) { - $tinfo->{'master_restart'}= 1; # We think so for now - MASTER_OPT: + my $master_opt= mtr_get_opts_from_file($master_opt_file); + + foreach my $opt ( @$master_opt ) { - my $master_opt= mtr_get_opts_from_file($master_opt_file); + my $value; - foreach my $opt ( @$master_opt ) + # The opt file is used both to send special options to the mysqld + # as well as pass special test case specific options to this + # script + + $value= mtr_match_prefix($opt, "--timezone="); + if ( defined $value ) { - my $value; - - # This is a dirty hack from old mysql-test-run, we use the opt - # file to flag other things as well, it is not a opt list at - # all - - $value= mtr_match_prefix($opt, "--timezone="); - if ( defined $value ) - { - $tinfo->{'timezone'}= $value; - last MASTER_OPT; - } - - $value= mtr_match_prefix($opt, "--result-file="); - if ( defined $value ) - { - $tinfo->{'result_file'}= "r/$value.result"; - $tinfo->{'master_restart'}= 0; - last MASTER_OPT; - } - - # If we set default time zone, remove the one we have - $value= mtr_match_prefix($opt, "--default-time-zone="); - if ( defined $value ) - { - $tinfo->{'master_opt'}= []; - } - + $tinfo->{'timezone'}= $value; + next; } - # Ok, this was a real option list, add it - push(@{$tinfo->{'master_opt'}}, @$master_opt); + $value= mtr_match_prefix($opt, "--result-file="); + if ( defined $value ) + { + # Specifies the file mysqltest should compare + # output against + $tinfo->{'result_file'}= "r/$value.result"; + next; + } + + # If we set default time zone, remove the one we have + $value= mtr_match_prefix($opt, "--default-time-zone="); + if ( defined $value ) + { + $tinfo->{'timezone'}= ""; + # Fallthrough, add this option + } + + # The --restart option forces a restart even if no special + # option is set. If the options are the same as next testcase + # there is no need to restart after the testcase + # has completed + if ( $opt eq "--force-restart" ) + { + $tinfo->{'force_restart'}= 1; + next; + } + + # Ok, this was a real option, add it + push(@{$tinfo->{'master_opt'}}, $opt); } } if ( -f $slave_opt_file ) { - $tinfo->{'slave_restart'}= 1; my $slave_opt= mtr_get_opts_from_file($slave_opt_file); foreach my $opt ( @$slave_opt ) @@ -417,7 +420,6 @@ sub collect_one_test_case($$$$$$$) { if ( -f $slave_mi_file ) { $tinfo->{'slave_mi'}= mtr_get_opts_from_file($slave_mi_file); - $tinfo->{'slave_restart'}= 1; } if ( -f $master_sh ) @@ -431,7 +433,6 @@ sub collect_one_test_case($$$$$$$) { else { $tinfo->{'master_sh'}= $master_sh; - $tinfo->{'master_restart'}= 1; } } @@ -446,7 +447,6 @@ sub collect_one_test_case($$$$$$$) { else { $tinfo->{'slave_sh'}= $slave_sh; - $tinfo->{'slave_restart'}= 1; } } @@ -551,17 +551,6 @@ sub collect_one_test_case($$$$$$$) { return; } } - - # We can't restart a running server that may be in use - - if ( $::glob_use_running_server and - ( $tinfo->{'master_restart'} or $tinfo->{'slave_restart'} ) ) - { - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Can't restart a running server"; - return; - } - } diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c53ca49a7e9..dd6e8dacbdc 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -65,7 +65,7 @@ use IO::Socket; use IO::Socket::INET; use Data::Dumper; use strict; -#use diagnostics; +use diagnostics; our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl our $glob_cygwin_perl= ($^O eq "cygwin"); # Cygwin Perl @@ -1357,10 +1357,13 @@ sub executable_setup () { $exe_mysqlslap= mtr_exe_exists("$path_client_bindir/mysqlslap"); } - # Look for mysql_fix_system_table script - $exe_mysql_fix_system_tables= - mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", - "$path_client_bindir/mysql_fix_privilege_tables"); + if ( ! $glob_win32 ) + { + # Look for mysql_fix_system_table script + $exe_mysql_fix_system_tables= + mtr_script_exists("$glob_basedir/scripts/mysql_fix_privilege_tables", + "$path_client_bindir/mysql_fix_privilege_tables"); + } if ( ! $opt_skip_ndbcluster) { @@ -1492,11 +1495,13 @@ sub environment_setup () { } $ENV{'LD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', qw($ENV{'LD_LIBRARY_PATH'}))); + $ENV{'LD_LIBRARY_PATHS'} ? + split(':', $ENV{'LD_LIBRARY_PATH'}) : ()); mtr_debug("LD_LIBRARY_PATH: $ENV{'LD_LIBRARY_PATH'}"); $ENV{'DYLD_LIBRARY_PATH'}= join(":", @ld_library_paths, - split(':', qw($ENV{'DYLD_LIBRARY_PATH'}))); + $ENV{'DYLD_LIBRARY_PATH'} ? + split(':', $ENV{'DYLD_LIBRARY_PATH'}) : ()); mtr_debug("DYLD_LIBRARY_PATH: $ENV{'DYLD_LIBRARY_PATH'}"); @@ -1527,22 +1532,25 @@ sub environment_setup () { # ---------------------------------------------------- # Setup env for NDB # ---------------------------------------------------- - $ENV{'NDB_MGM'}= $exe_ndb_mgm; + if ( ! $opt_skip_ndbcluster ) + { + $ENV{'NDB_MGM'}= $exe_ndb_mgm; - $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; - $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave; + $ENV{'NDBCLUSTER_PORT'}= $opt_ndbcluster_port; + $ENV{'NDBCLUSTER_PORT_SLAVE'}= $opt_ndbcluster_port_slave; - $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test; + $ENV{'NDB_EXTRA_TEST'}= $opt_ndb_extra_test; - $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'}; - $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'}; - $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; - $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; - $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; + $ENV{'NDB_BACKUP_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_DATA_DIR'}= $clusters->[0]->{'data_dir'}; + $ENV{'NDB_TOOLS_DIR'}= $path_ndb_tools_dir; + $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; + $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; - $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; - $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; - $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; + $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; + $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; + $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; + } # ---------------------------------------------------- # Setup env for IM @@ -2817,6 +2825,17 @@ sub run_testcase ($) { if ($master_restart or $slave_restart) { + # Can't restart a running server that may be in use + if ( $glob_use_running_server ) + { + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Can't restart a running server"; + + mtr_report_test_name($tinfo); + mtr_report_test_skipped($tinfo); + return; + } + run_testcase_stop_servers($tinfo, $master_restart, $slave_restart); } my $died= mtr_record_dead_children(); @@ -2884,13 +2903,10 @@ sub run_testcase ($) { # ---------------------------------------------------------------------- # Stop Instance Manager if we are processing an IM-test case. # ---------------------------------------------------------------------- - - if ( ! $glob_use_running_server and $tinfo->{'component_id'} eq 'im' ) + if ( $tinfo->{'component_id'} eq 'im' and + mtr_im_stop($instance_manager, $tinfo->{'name'}) != 0 ) { - unless ( mtr_im_stop($instance_manager, $tinfo->{'name'}) ) - { - mtr_error("Failed to stop Instance Manager.") - } + mtr_error("Failed to stop Instance Manager.") } } @@ -3516,48 +3532,38 @@ sub run_testcase_need_master_restart($) if ( $tinfo->{'master_sh'} ) { $do_restart= 1; # Always restart if script to run - mtr_verbose("Restart because: Always restart if script to run"); + mtr_verbose("Restart master: Always restart if script to run"); + } + if ( $tinfo->{'force_restart'} ) + { + $do_restart= 1; # Always restart if --force-restart in -opt file + mtr_verbose("Restart master: Restart forced with --force-restart"); } elsif ( ! $opt_skip_ndbcluster and $tinfo->{'ndb_test'} == 0 and $clusters->[0]->{'pid'} != 0 ) { $do_restart= 1; # Restart without cluster - mtr_verbose("Restart because: Test does not need cluster"); + mtr_verbose("Restart master: Test does not need cluster"); } elsif ( ! $opt_skip_ndbcluster and $tinfo->{'ndb_test'} == 1 and $clusters->[0]->{'pid'} == 0 ) { $do_restart= 1; # Restart with cluster - mtr_verbose("Restart because: Test need cluster"); + mtr_verbose("Restart master: Test need cluster"); } elsif( $tinfo->{'component_id'} eq 'im' ) { $do_restart= 1; - mtr_verbose("Restart because: Always restart for im tests"); + mtr_verbose("Restart master: Always restart for im tests"); } - elsif ( $master->[0]->{'running_master_is_special'} and - $master->[0]->{'running_master_is_special'}->{'timezone'} eq - $tinfo->{'timezone'} and - mtr_same_opts($master->[0]->{'running_master_is_special'}->{'master_opt'}, - $tinfo->{'master_opt'}) ) - { - # If running master was started with special settings, but - # the current test requires the same ones, we *don't* restart. - $do_restart= 0; - mtr_verbose("Skip restart: options are equal " . - join(" ", @{$tinfo->{'master_opt'}})); - } - elsif ( $tinfo->{'master_restart'} ) + elsif ( $master->[0]->{'running_master_options'} and + $master->[0]->{'running_master_options'}->{'timezone'} ne + $tinfo->{'timezone'}) { $do_restart= 1; - mtr_verbose("Restart because: master_restart"); - } - elsif ( $master->[0]->{'running_master_is_special'} ) - { - $do_restart= 1; - mtr_verbose("Restart because: running_master_is_special"); + mtr_verbose("Restart master: Different timezone"); } # Check that running master was started with same options # as the current test requires @@ -3565,14 +3571,14 @@ sub run_testcase_need_master_restart($) $tinfo->{'master_opt'}) ) { $do_restart= 1; - mtr_verbose("Restart because: running with different options '" . + mtr_verbose("Restart master: running with different options '" . join(" ", @{$tinfo->{'master_opt'}}) . "' != '" . join(" ", @{$master->[0]->{'start_opts'}}) . "'" ); } elsif( ! $master->[0]->{'pid'} ) { $do_restart= 1; - mtr_verbose("Restart because: master is not started"); + mtr_verbose("Restart master: master is not started"); } return $do_restart; @@ -3587,7 +3593,7 @@ sub run_testcase_need_slave_restart($) if ( $max_slave_num == 0) { - mtr_verbose("No testcase use slaves, no slave restarts"); + mtr_verbose("Skip slave restart: No testcase use slaves"); } else { @@ -3605,12 +3611,12 @@ sub run_testcase_need_slave_restart($) if ($any_slave_started) { - mtr_verbose("Any slave is started, need to restart"); + mtr_verbose("Restart slave: Slave is started, always restart"); $do_slave_restart= 1; } elsif ( $tinfo->{'slave_num'} ) { - mtr_verbose("Test need slave, check for restart"); + mtr_verbose("Restart slave: Test need slave"); $do_slave_restart= 1; } } @@ -3632,22 +3638,16 @@ sub run_testcase_need_slave_restart($) sub run_testcase_stop_servers($$$) { my ($tinfo, $do_restart, $do_slave_restart)= @_; - - if ( $glob_use_running_server || $glob_use_embedded_server ) - { - return; - } - my $pid; my %admin_pids; # hash of admin processes that requests shutdown my @kill_pids; # list of processes to shutdown/kill - # Remember if we restarted for this test case + # Remember if we restarted for this test case (count restarts) $tinfo->{'restarted'}= $do_restart; if ( $do_restart ) { - delete $master->[0]->{'running_master_is_special'}; # Forget history + delete $master->[0]->{'running_master_options'}; # Forget history # Start shutdown of all started masters foreach my $mysqld (@{$master}) @@ -3697,7 +3697,7 @@ sub run_testcase_stop_servers($$$) { if ( $do_restart || $do_slave_restart ) { - delete $slave->[0]->{'running_slave_is_special'}; # Forget history + delete $slave->[0]->{'running_slave_options'}; # Forget history # Start shutdown of all started slaves foreach my $mysqld (@{$slave}) @@ -3781,18 +3781,13 @@ sub run_testcase_stop_servers($$$) { sub run_testcase_start_servers($) { my $tinfo= shift; - my $tname= $tinfo->{'name'}; - if ( $glob_use_running_server or $glob_use_embedded_server ) - { - return 0; - } - # ------------------------------------------------------- # Init variables that can change between server starts # ------------------------------------------------------- $ENV{'TZ'}= $tinfo->{'timezone'}; + mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}"); if ( $tinfo->{'component_id'} eq 'mysqld' ) { @@ -3837,11 +3832,8 @@ sub run_testcase_start_servers($) { mysqld_start($master->[1],$tinfo->{'master_opt'},[]); } - if ( $tinfo->{'master_restart'} ) - { - # Save this test case information, so next can examine it - $master->[0]->{'running_master_is_special'}= $tinfo; - } + # Save this test case information, so next can examine it + $master->[0]->{'running_master_options'}= $tinfo; } elsif ( ! $opt_skip_im and $tinfo->{'component_id'} eq 'im' ) { @@ -3888,12 +3880,8 @@ sub run_testcase_start_servers($) { } } - if ( $tinfo->{'slave_restart'} ) - { - # Save this test case information, so next can examine it - $slave->[0]->{'running_slave_is_special'}= $tinfo; - } - + # Save this test case information, so next can examine it + $slave->[0]->{'running_slave_options'}= $tinfo; } # Wait for clusters to start @@ -3969,7 +3957,7 @@ sub run_check_testcase ($$) { my $res = mtr_run_test($exe_mysqltest,$args, "include/check-testcase.test", "", "", ""); - if ( $res == 1 and $mode = "after") + if ( $res == 1 and $mode eq "after") { mtr_run("diff",["-u", "$opt_vardir/tmp/$name.result", diff --git a/mysql-test/t/bdb-alter-table-2-master.opt b/mysql-test/t/bdb-alter-table-2-master.opt index 15ad73c500f..c2dca33445b 100644 --- a/mysql-test/t/bdb-alter-table-2-master.opt +++ b/mysql-test/t/bdb-alter-table-2-master.opt @@ -1,2 +1,2 @@ ---skip-external-locking +--force-restart diff --git a/mysql-test/t/not_embedded_server-master.opt b/mysql-test/t/not_embedded_server-master.opt index 35fcc5f30c6..cef79bc8585 100644 --- a/mysql-test/t/not_embedded_server-master.opt +++ b/mysql-test/t/not_embedded_server-master.opt @@ -1 +1 @@ ---loose-to-force-a-restart +--force-restart From 6c0ad741276d36711f02de6510257f19053ac4b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 15:45:35 +0200 Subject: [PATCH 114/235] mtr_im_stop returns 1 if all is well --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dd6e8dacbdc..1759b357eb1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2904,7 +2904,7 @@ sub run_testcase ($) { # Stop Instance Manager if we are processing an IM-test case. # ---------------------------------------------------------------------- if ( $tinfo->{'component_id'} eq 'im' and - mtr_im_stop($instance_manager, $tinfo->{'name'}) != 0 ) + !mtr_im_stop($instance_manager, $tinfo->{'name'}) ) { mtr_error("Failed to stop Instance Manager.") } From 576fd5a5eee99c15923f39750ffb3a20941be705 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 19:40:55 +0200 Subject: [PATCH 115/235] Check that TERM has been set to avoid problem "Error opening terminal: unknown" when the script is executed using non interactive ssh Set TERM to "linux" as default netware/BUILD/mwenv: Check that TERM has been set to avoid problem "Error opening terminal: unknown" when the script is executed using non interactive ssh --- netware/BUILD/mwenv | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index d8d53293b2c..dd055ad8270 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -46,3 +46,13 @@ export LD='mwldnlm' export LDFLAGS='-entry _LibCPrelude -exit _LibCPostlude -map -flags pseudopreemption' export RANLIB=: export STRIP=: + +# +# Check that TERM has been set to avoid problem "Error opening +# terminal: unknown" when the script is executed using non interactive ssh +# +if test -z "$TERM" -o "$TERM"=dumb +then + export TERM=linux +fi + From d6d469237270047422f78224a549d5956a62652c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 21:53:43 +0200 Subject: [PATCH 116/235] Fixes for embedded server test client/mysqltest.c: Fix typo --- client/mysqltest.c | 2 +- mysql-test/mysql-test-run.pl | 18 ++++++++++++++---- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 0a9549acc47..b671147e1d7 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1433,7 +1433,7 @@ void do_source(struct st_command *command) #ifdef __WIN__ -/* Variables used for temuprary sh files used for emulating Unix on Windows */ +/* Variables used for temporary sh files used for emulating Unix on Windows */ char tmp_sh_name[64], tmp_sh_cmd[70]; void init_tmp_sh_file() diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1759b357eb1..0e340e47ae8 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1418,7 +1418,7 @@ sub executable_setup () { { $exe_mysql_client_test= mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded", - "$glob_basedir/tests/mysqltest_embedded"); + "$path_client_bindir/mysql_client_test_embedded"); } else { @@ -3107,7 +3107,7 @@ sub mysqld_arguments ($$$$$) { $prefix= "--server-arg="; } else { # We can't pass embedded server --no-defaults - mtr_add_arg($args, "%s--no-defaults", $prefix); + mtr_add_arg($args, "--no-defaults"); } mtr_add_arg($args, "%s--console", $prefix); @@ -3529,7 +3529,12 @@ sub run_testcase_need_master_restart($) # We try to find out if we are to restart the master(s) my $do_restart= 0; # Assumes we don't have to - if ( $tinfo->{'master_sh'} ) + if ( $glob_use_embedded_server ) + { + mtr_verbose("Never start or restart for embedded server"); + return $do_restart; + } + elsif ( $tinfo->{'master_sh'} ) { $do_restart= 1; # Always restart if script to run mtr_verbose("Restart master: Always restart if script to run"); @@ -3591,7 +3596,12 @@ sub run_testcase_need_slave_restart($) # We try to find out if we are to restart the slaves my $do_slave_restart= 0; # Assumes we don't have to - if ( $max_slave_num == 0) + if ( $glob_use_embedded_server ) + { + mtr_verbose("Never start or restart for embedded server"); + return $do_slave_restart; + } + elsif ( $max_slave_num == 0) { mtr_verbose("Skip slave restart: No testcase use slaves"); } From e9b7cc09e5ab9ee8d4b6a879a7ed2282f45c6f8a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 11 Oct 2006 23:35:52 -0600 Subject: [PATCH 117/235] Revert patch for bug #19764, which did not work with prepared statements. BitKeeper/deleted/.del-show_check-master.opt: Delete: mysql-test/t/show_check-master.opt --- mysql-test/r/show_check.result | 17 +---------------- mysql-test/t/show_check-master.opt | 1 - mysql-test/t/show_check.test | 14 +------------- sql/sql_lex.cc | 1 - sql/sql_lex.h | 7 ------- sql/sql_parse.cc | 6 +++--- sql/sql_yacc.yy | 1 - 7 files changed, 5 insertions(+), 42 deletions(-) delete mode 100644 mysql-test/t/show_check-master.opt diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 3c90af924e4..762019be313 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -630,19 +630,4 @@ SHOW TABLES FROM no_such_database; ERROR 42000: Unknown database 'no_such_database' SHOW COLUMNS FROM no_such_table; ERROR 42S02: Table 'test.no_such_table' doesn't exist -flush status; -show status like 'slow_queries'; -Variable_name Value -Slow_queries 0 -show tables; -Tables_in_test -show status like 'slow_queries'; -Variable_name Value -Slow_queries 0 -select 1 from information_schema.tables limit 1; -1 -1 -show status like 'slow_queries'; -Variable_name Value -Slow_queries 1 -End of 5.0 tests. +End of 5.0 tests diff --git a/mysql-test/t/show_check-master.opt b/mysql-test/t/show_check-master.opt deleted file mode 100644 index 3eb98fc3d6b..00000000000 --- a/mysql-test/t/show_check-master.opt +++ /dev/null @@ -1 +0,0 @@ ---log-slow-queries --log-long-format --log-queries-not-using-indexes diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 1fc22e38f73..07426193dcf 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -507,16 +507,4 @@ SHOW TABLES FROM no_such_database; SHOW COLUMNS FROM no_such_table; -# -# Bug #19764: SHOW commands end up in the slow log as table scans -# -flush status; -show status like 'slow_queries'; -show tables; -show status like 'slow_queries'; -# Table scan query, to ensure that slow_queries does still get incremented -# (mysqld is started with --log-queries-not-using-indexes) -select 1 from information_schema.tables limit 1; -show status like 'slow_queries'; - ---echo End of 5.0 tests. +--echo End of 5.0 tests diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 01db96291ff..788276ac654 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -173,7 +173,6 @@ void lex_start(THD *thd, uchar *buf,uint length) lex->spcont= NULL; lex->proc_list.first= 0; lex->escape_used= FALSE; - lex->is_show_command= FALSE; lex->reset_query_tables_list(FALSE); lex->nest_level=0 ; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 1eae81732b7..fdf14c691e9 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1016,13 +1016,6 @@ typedef struct st_lex : public Query_tables_list bool escape_used; - /* - Prevent SHOW commands from being written to the slow queries log. - This is fixed properly in MySQL 5.1, but a quick hack is used in 5.0 - to achieve the same result. - */ - bool is_show_command; - st_lex(); virtual ~st_lex() diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 90cef7796fb..18d048df393 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2150,10 +2150,10 @@ void log_slow_statement(THD *thd) thd->end_time(); // Set start time /* - Do not log administrative or SHOW statements unless the appropriate - option is set; do not log into slow log if reading from backup. + Do not log administrative statements unless the appropriate option is + set; do not log into slow log if reading from backup. */ - if (thd->enable_slow_log && !thd->user_time && !thd->lex->is_show_command) + if (thd->enable_slow_log && !thd->user_time) { thd->proc_info="logging slow query"; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 3d31b37062c..cb105d05332 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -6412,7 +6412,6 @@ opt_table_sym: show: SHOW { LEX *lex=Lex; - lex->is_show_command= TRUE; lex->wild=0; lex->lock_option= TL_READ; mysql_init_select(lex); From 62e102b42eb286c5fc4f5ed2e11357a08c930069 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 11:21:12 +0400 Subject: [PATCH 118/235] 5.0-specific fixes when merging the fix for bug #11655 and bug #20927 from 4.1 mysql-test/r/func_time.result: Fixed func_time test when merging the fix for bug #11655 and bug #20927 to 5.0 sql/item_timefunc.cc: Fixed compilation when merging the fix for bug #11655 and bug #20927 to 5.0 --- mysql-test/r/func_time.result | 2 +- sql/item_timefunc.cc | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 0a766fcdc63..91bd3722299 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -898,7 +898,7 @@ CREATE TABLE t1(f1 TIME); INSERT INTO t1 VALUES('916:00:00 a'); Warnings: Warning 1265 Data truncated for column 'f1' at row 1 -Warning 1264 Data truncated; out of range for column 'f1' at row 1 +Warning 1264 Out of range value adjusted for column 'f1' at row 1 SELECT * FROM t1; f1 838:59:59 diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index e320275f53d..35cffa9c542 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -120,7 +120,7 @@ static bool make_datetime_with_warn(date_time_format_types format, TIME *ltime, return 0; make_truncated_value_warning(current_thd, str->ptr(), str->length(), - MYSQL_TIMESTAMP_TIME); + MYSQL_TIMESTAMP_TIME, NullS); return make_datetime(format, ltime, str); } @@ -146,7 +146,7 @@ static bool make_time_with_warn(const DATE_TIME_FORMAT *format, if (warning) { make_truncated_value_warning(current_thd, str->ptr(), str->length(), - MYSQL_TIMESTAMP_TIME); + MYSQL_TIMESTAMP_TIME, NullS); make_time(format, l_time, str); } @@ -207,7 +207,8 @@ overflow: char buf[22]; int len= (int)(longlong10_to_str(seconds, buf, unsigned_flag ? 10 : -10) - buf); - make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME); + make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME, + NullS); return 1; } @@ -2960,7 +2961,8 @@ String *Item_func_maketime::val_str(String *str) char *ptr= longlong10_to_str(hour, buf, args[0]->unsigned_flag ? 10 : -10); int len = (int)(ptr - buf) + my_sprintf(ptr, (ptr, ":%02u:%02u", (uint)minute, (uint)second)); - make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME); + make_truncated_value_warning(current_thd, buf, len, MYSQL_TIMESTAMP_TIME, + NullS); } if (make_time_with_warn((DATE_TIME_FORMAT *) 0, <ime, str)) From 6cbc74a70678ff9c11c140559b4cbc62bda3649e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 10:27:44 +0200 Subject: [PATCH 119/235] Add DBUG_ASSERT to check that mysql is not null when mysql_reconnect is called Add DBUG_PRINT to show the value of mysql->reconnect --- sql-common/client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sql-common/client.c b/sql-common/client.c index ff5f1ef150a..3acd763c054 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2215,6 +2215,8 @@ my_bool mysql_reconnect(MYSQL *mysql) { MYSQL tmp_mysql; DBUG_ENTER("mysql_reconnect"); + DBUG_ASSERT(mysql); + DBUG_PRINT("enter", ("mysql->reconnect: %d", mysql->reconnect)); if (!mysql->reconnect || (mysql->server_status & SERVER_STATUS_IN_TRANS) || !mysql->host_info) From 1f837a5c76b89ea99b4064494243bd438e5af552 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 10:49:59 +0200 Subject: [PATCH 120/235] Only print cur_file->filename if cur_file->file is set MOve DBUG_ASSERT(result_file_name) to after DBUG_ENTER Change type of "reconnect" variable from int to my_bool, reconnect didn't work on Solaris without that --- client/mysqltest.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index b671147e1d7..db15c6c43dd 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -668,9 +668,11 @@ void close_files() DBUG_ENTER("close_files"); for (; cur_file >= file_stack; cur_file--) { - DBUG_PRINT("info", ("file_name: %s", cur_file->file_name)); if (cur_file->file && cur_file->file != stdin) + { + DBUG_PRINT("info", ("closing file: %s", cur_file->file_name)); my_fclose(cur_file->file, MYF(0)); + } my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); cur_file->file_name= 0; } @@ -950,8 +952,8 @@ err: void check_result(DYNAMIC_STRING* ds) { - DBUG_ASSERT(result_file_name); DBUG_ENTER("check_result"); + DBUG_ASSERT(result_file_name); switch (dyn_string_cmp(ds, result_file_name)) { @@ -2707,12 +2709,15 @@ char *get_string(char **to_ptr, char **from_ptr, void set_reconnect(MYSQL* mysql, int val) { + DBUG_ENTER("set_reconnect"); + DBUG_PRINT("info", ("val: %d", val)); #if MYSQL_VERSION_ID < 50000 mysql->reconnect= val; #else - int reconnect= val; + my_bool reconnect= val; mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); #endif + DBUG_VOID_RETURN; } From 00f420db13751bfe36a1d382e44541896134e5cb Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 11:29:13 +0200 Subject: [PATCH 121/235] Fix unhandled exception in mysql-test-run.pl, creating a dir that already exist mysql-test/lib/mtr_process.pl: Remove junk code/comments Moved the creation of var/log out of function mtr_kill_leftovers mysql-test/mysql-test-run.pl: Rename 'kill_running_server' to more appropriate name 'kill_running_servers' If no var/log dir exists when mtr_kill_leftovers is started it should be created Remove "unless" syntax, too perlish Fix typo --- mysql-test/lib/mtr_process.pl | 13 ------------- mysql-test/mysql-test-run.pl | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 5e21248790e..2831c179ea5 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -339,19 +339,6 @@ sub mtr_kill_leftovers () { mtr_report("Killing Possible Leftover Processes"); mtr_debug("mtr_kill_leftovers(): started."); - mkpath("$::opt_vardir/log"); # Needed for mysqladmin log - - # Stop or kill Instance Manager and all its children. If we failed to do - # that, we can only abort -- there is nothing left to do. - -# mtr_error("Failed to stop Instance Manager.") -# unless mtr_im_stop($::instance_manager); - - # Start shutdown of masters and slaves. Don't touch IM-managed mysqld - # instances -- they should be stopped by mtr_im_stop(). - - mtr_debug("Shutting down mysqld-instances..."); - my @kill_pids; my %admin_pids; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0e340e47ae8..629ba00f8f1 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -310,7 +310,7 @@ sub command_line_setup (); sub datadir_setup (); sub executable_setup (); sub environment_setup (); -sub kill_running_server (); +sub kill_running_servers (); sub cleanup_stale_files (); sub check_ssl_support ($); sub check_running_as_root(); @@ -1802,7 +1802,7 @@ sub handle_int_signal () { # ############################################################################## -sub kill_running_server () { +sub kill_running_servers () { if ( $opt_fast or $glob_use_embedded_server ) { @@ -1820,6 +1820,13 @@ sub kill_running_server () { # started from this run of the script, this is terminating # leftovers from previous runs. + if ( ! -d $opt_vardir ) + { + # The "var" dir does not exist already + # the processes that mtr_kill_leftovers start will write + # their log files to var/log so it should be created + mkpath("$opt_vardir/log"); + } mtr_kill_leftovers(); } } @@ -2416,9 +2423,9 @@ sub initialize_servers () { if ( ! $glob_use_running_server ) { - kill_running_server(); + kill_running_servers(); - unless ( $opt_start_dirty ) + if ( ! $opt_start_dirty ) { cleanup_stale_files(); mysql_install_db(); @@ -3782,7 +3789,7 @@ sub run_testcase_stop_servers($$$) { # # run_testcase_start_servers # -# Start the servers neede by this test case +# Start the servers needed by this test case # # RETURN # 0 OK From aed3bd413ddf4bd90085318f80daf74a7cea37e1 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 12:11:23 +0200 Subject: [PATCH 122/235] Switch to use yaSSL instead of OpenSSL on Netware --- netware/BUILD/compile-netware-max | 2 +- netware/BUILD/compile-netware-max-debug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/netware/BUILD/compile-netware-max b/netware/BUILD/compile-netware-max index ec737d4615c..3286c3c693b 100644 --- a/netware/BUILD/compile-netware-max +++ b/netware/BUILD/compile-netware-max @@ -15,7 +15,7 @@ suffix="max" extra_configs=" \ --with-innodb \ --with-embedded-server \ - --with-openssl \ + --with-yassl \ " . $path/compile-netware-END diff --git a/netware/BUILD/compile-netware-max-debug b/netware/BUILD/compile-netware-max-debug index ea3553ae6e1..e3155cbd7d7 100644 --- a/netware/BUILD/compile-netware-max-debug +++ b/netware/BUILD/compile-netware-max-debug @@ -15,7 +15,7 @@ extra_configs=" \ --with-innodb \ --with-debug=full \ --with-embedded-server \ - --with-openssl \ + --with-yassl \ " . $path/compile-netware-END From a1a0b3deabf4f8415ca1361f3ce12bfb5cab5b85 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 12:14:50 +0200 Subject: [PATCH 123/235] Only one switch for ssl(--with-ssl) in 5.1 --- netware/BUILD/compile-netware-max | 2 +- netware/BUILD/compile-netware-max-debug | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/netware/BUILD/compile-netware-max b/netware/BUILD/compile-netware-max index 3286c3c693b..d8278a4e915 100644 --- a/netware/BUILD/compile-netware-max +++ b/netware/BUILD/compile-netware-max @@ -15,7 +15,7 @@ suffix="max" extra_configs=" \ --with-innodb \ --with-embedded-server \ - --with-yassl \ + --with-ssl \ " . $path/compile-netware-END diff --git a/netware/BUILD/compile-netware-max-debug b/netware/BUILD/compile-netware-max-debug index e3155cbd7d7..de1b5dd17cc 100644 --- a/netware/BUILD/compile-netware-max-debug +++ b/netware/BUILD/compile-netware-max-debug @@ -15,7 +15,7 @@ extra_configs=" \ --with-innodb \ --with-debug=full \ --with-embedded-server \ - --with-yassl \ + --with-ssl \ " . $path/compile-netware-END From 1bb09d53ad6463fb29d24905ebeae1452d054ec5 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 12:19:23 +0200 Subject: [PATCH 124/235] Look for mysql_client_test in $path_client_bindir --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 629ba00f8f1..d4555e8ac00 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1423,7 +1423,7 @@ sub executable_setup () { else { $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test"); + mtr_exe_exists("$path_client_bindir/mysql_client_test"); } } From c5cebf205f9eae1d9e94ee2477fab12a3fee432f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 13:28:18 +0200 Subject: [PATCH 125/235] Use libc-2003 if available else default to libc --- netware/BUILD/mwenv | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index dd055ad8270..bc797c442ab 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -26,8 +26,17 @@ WINE_BUILD_DIR=`echo "$BUILD_DIR" | sed 's_'$base_unix_part'/__'` WINE_BUILD_DIR="$base/$WINE_BUILD_DIR" echo "WINE_BUILD_DIR: $WINE_BUILD_DIR" -export MWCNWx86Includes="$MYDEV/libc/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV" -export MWNWx86Libraries="$MYDEV/libc/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD" +# Look for libc, MySQL 5.0.x uses libc-2003 by default +libcdir="$MYDEV/libc-2003" +if test ! -d $libcdir +then + # The libcdir didn't exist, set default + libc_dir="$MYDEV/libc" +fi +echo "Using libc in $libc_dir"; + +export MWCNWx86Includes="$libc_dir/include;$MYDEV/fs64/headers;$MYDEV/zlib-1.2.3;$WINE_BUILD_DIR/include;$MYDEV" +export MWNWx86Libraries="$libc_dir/imports;$MYDEV/mw/lib;$MYDEV/fs64/imports;$MYDEV/zlib-1.2.3;$MYDEV/openssl;$WINE_BUILD_DIR/netware/BUILD" export MWNWx86LibraryFiles="libcpre.o;libc.imp;netware.imp;mwcrtl.lib;mwcpp.lib;libz.a;neb.imp;zPublics.imp;knetware.imp" export WINEPATH="$MYDEV/mw/bin" @@ -56,3 +65,5 @@ then export TERM=linux fi +# Print all env. variables +export From 3fb85dcad140fc23137525729868f0f519871964 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 13:31:41 +0200 Subject: [PATCH 126/235] 5.1 should use libc-2006 by default --- netware/BUILD/mwenv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index bc797c442ab..c3869d2ec90 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -26,8 +26,8 @@ WINE_BUILD_DIR=`echo "$BUILD_DIR" | sed 's_'$base_unix_part'/__'` WINE_BUILD_DIR="$base/$WINE_BUILD_DIR" echo "WINE_BUILD_DIR: $WINE_BUILD_DIR" -# Look for libc, MySQL 5.0.x uses libc-2003 by default -libcdir="$MYDEV/libc-2003" +# Look for libc, MySQL 5.1.x uses libc-2006 by default +libcdir="$MYDEV/libc-2006" if test ! -d $libcdir then # The libcdir didn't exist, set default From 84617169620e26a23d10c9051ccfa8a3c42db95f Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 13:49:12 +0200 Subject: [PATCH 127/235] Add win paths for mysql_client_test --- mysql-test/mysql-test-run.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index d4555e8ac00..29acd25138f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1417,13 +1417,14 @@ sub executable_setup () { if ( $glob_use_embedded_server ) { $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded", - "$path_client_bindir/mysql_client_test_embedded"); + mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); } else { $exe_mysql_client_test= - mtr_exe_exists("$path_client_bindir/mysql_client_test"); + mtr_exe_exists("$glob_basedir/tests/mysql_client_test", + "$glob_basedir/tests/release/mysql_client_test" + "$glob_basedir/tests/debug/mysql_client_test"); } } From 7405e7792de531d34cab00d1eadf011539e95cf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 13:50:50 +0200 Subject: [PATCH 128/235] Move the reconnect variable to beginning of function Fix warning about value from "*ptr++" not being used. Changed it to ptr++ --- client/mysqltest.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index db15c6c43dd..e2317560404 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -2709,12 +2709,12 @@ char *get_string(char **to_ptr, char **from_ptr, void set_reconnect(MYSQL* mysql, int val) { + my_bool reconnect= val; DBUG_ENTER("set_reconnect"); DBUG_PRINT("info", ("val: %d", val)); #if MYSQL_VERSION_ID < 50000 - mysql->reconnect= val; + mysql->reconnect= reconnect; #else - my_bool reconnect= val; mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect); #endif DBUG_VOID_RETURN; @@ -3609,7 +3609,7 @@ void scan_command_for_warnings(struct st_command *command) *end= save; } - *ptr++; + ptr++; } DBUG_VOID_RETURN; } From dd519d114ab402b944f9f50feeff5f268b780097 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 14:14:54 +0200 Subject: [PATCH 129/235] Make all compile-netware-* scripts executable netware/BUILD/compile-netware-max: Change mode to -rwxrwxr-x netware/BUILD/compile-netware-max-debug: Change mode to -rwxrwxr-x netware/BUILD/compile-netware-src: Change mode to -rwxrwxr-x --- netware/BUILD/compile-netware-max | 0 netware/BUILD/compile-netware-max-debug | 0 netware/BUILD/compile-netware-src | 0 3 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 netware/BUILD/compile-netware-max mode change 100644 => 100755 netware/BUILD/compile-netware-max-debug mode change 100644 => 100755 netware/BUILD/compile-netware-src diff --git a/netware/BUILD/compile-netware-max b/netware/BUILD/compile-netware-max old mode 100644 new mode 100755 diff --git a/netware/BUILD/compile-netware-max-debug b/netware/BUILD/compile-netware-max-debug old mode 100644 new mode 100755 diff --git a/netware/BUILD/compile-netware-src b/netware/BUILD/compile-netware-src old mode 100644 new mode 100755 From e203f0e578a064bee54d600b2c70424b9f9c9365 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 16:17:09 +0200 Subject: [PATCH 130/235] Add missing semicolon --- mysql-test/mysql-test-run.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 29acd25138f..0c46bbeac79 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1423,7 +1423,7 @@ sub executable_setup () { { $exe_mysql_client_test= mtr_exe_exists("$glob_basedir/tests/mysql_client_test", - "$glob_basedir/tests/release/mysql_client_test" + "$glob_basedir/tests/release/mysql_client_test", "$glob_basedir/tests/debug/mysql_client_test"); } } From a28a9c278638974ce0173eb5329f5946d209bd33 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 17:55:06 +0200 Subject: [PATCH 131/235] Use autorun.sh from BUILD/ instead of netware specific version --- netware/BUILD/compile-netware-END | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index c5c08cea908..a8d829499bd 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -15,11 +15,11 @@ if test -e "Makefile"; then make -k clean; fi rm -f */.deps/*.P rm -rf Makefile.in.bk -# Metrowerks enviornment +# Setup Metrowerks environment . $path/mwenv -# run auto tools -. $path/compile-AUTOTOOLS +# Run autotools(use BUILD/autorun.sh) +. BUILD/autorun.sh # configure ./configure $base_configs $extra_configs From 7bcd1f9f54529938ea0a0dabb40a184c413a6174 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 20:02:17 +0200 Subject: [PATCH 132/235] Add ATTRIBUTE_FORMAT for _db_doprnt, it will catch problems with DBUG_PRINT format specifiers include/my_dbug.h: Add ATTRIBUTE_FORMAT for _db_doprnt, it will catch problems with DBUG_PRINT format specifiers --- include/my_dbug.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/my_dbug.h b/include/my_dbug.h index bf2e8d9969b..8a8d622e2a3 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -36,7 +36,8 @@ extern void _db_enter_(const char *_func_,const char *_file_,uint _line_, extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_, uint *_slevel_); extern void _db_pargs_(uint _line_,const char *keyword); -extern void _db_doprnt_ _VARARGS((const char *format,...)); +extern void _db_doprnt_ _VARARGS((const char *format,...)) + ATTRIBUTE_FORMAT(printf, 1, 2); extern void _db_dump_(uint _line_,const char *keyword,const char *memory, uint length); extern void _db_output_(uint flag); From 23e941505592fa7f282f47d12e89e63ef236f2ca Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 20:15:56 +0200 Subject: [PATCH 133/235] Add ATTRIBUTE_FORMAT specifier to _db_doprnt, which is used by DBUG_PRINT This will hopefully avoiid annoying crashes when running with --debug Fix warnings from the above in mysqltest.c client/mysqltest.c: Fix format specifier warnings in mysqltest.c include/my_dbug.h: Add ATTRIBUTE_FORMAT specifier to _db_doprnt, which is used by DBUG_PRINT This will hopefully avoiid annoying crashes when running with --debug --- client/mysqltest.c | 8 +++----- include/my_dbug.h | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index e2317560404..4aa30ba3f1e 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -890,7 +890,7 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) die(NullS); if (!eval_result && (uint) stat_info.st_size != ds->length) { - DBUG_PRINT("info",("Size differs: result size: %u file size: %u", + DBUG_PRINT("info",("Size differs: result size: %u file size: %llu", ds->length, stat_info.st_size)); DBUG_PRINT("info",("result: '%s'", ds->str)); DBUG_RETURN(RESULT_LENGTH_MISMATCH); @@ -2558,7 +2558,7 @@ void do_get_errcodes(struct st_command *command) *to_ptr= 0; to->type= ERR_SQLSTATE; - DBUG_PRINT("info", ("ERR_SQLSTATE: %d", to->code.sqlstate)); + DBUG_PRINT("info", ("ERR_SQLSTATE: %s", to->code.sqlstate)); } else if (*p == 's') { @@ -4317,7 +4317,7 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt, bind[i].is_null= &is_null[i]; bind[i].length= &length[i]; - DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %d", + DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %lu", i, bind[i].buffer_type, bind[i].buffer_length)); } @@ -7267,5 +7267,3 @@ void replace_dynstr_append_uint(DYNAMIC_STRING *ds, uint val) char *end= longlong10_to_str(val, buff, 10); replace_dynstr_append_mem(ds, buff, end - buff); } - - diff --git a/include/my_dbug.h b/include/my_dbug.h index 711ece4335c..d2f6e40f3c6 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -35,7 +35,8 @@ extern void _db_enter_(const char *_func_,const char *_file_,uint _line_, extern void _db_return_(uint _line_,const char **_sfunc_,const char **_sfile_, uint *_slevel_); extern void _db_pargs_(uint _line_,const char *keyword); -extern void _db_doprnt_ _VARARGS((const char *format,...)); +extern void _db_doprnt_ _VARARGS((const char *format,...)) + ATTRIBUTE_FORMAT(printf, 1, 2); extern void _db_dump_(uint _line_,const char *keyword,const char *memory, uint length); extern void _db_output_(); From 7a9085c68b1b3945346db9b2e98a90b1b2b96369 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 20:52:53 +0200 Subject: [PATCH 134/235] Skip looking for ndbapi-examples in 4.1, not part of dist --- mysql-test/mysql-test-run.pl | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0c46bbeac79..dc2212f953b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1386,11 +1386,14 @@ sub executable_setup () { mtr_exe_exists("$ndb_path/src/kernel/ndbd", "$glob_basedir/bin/ndbd"); - $path_ndb_examples_dir= - mtr_path_exists("$ndb_path/ndbapi-examples", - "$ndb_path/examples"); - $exe_ndb_example= - mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + if ( $mysql_version_id >= 50000 ) + { + $path_ndb_examples_dir= + mtr_path_exists("$ndb_path/ndbapi-examples", + "$ndb_path/examples"); + $exe_ndb_example= + mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + } } # Look for the udf_example library @@ -1548,8 +1551,11 @@ sub environment_setup () { $ENV{'NDB_TOOLS_OUTPUT'}= $path_ndb_testrun_log; $ENV{'NDB_CONNECTSTRING'}= $opt_ndbconnectstring; - $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; - $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; + if ( $mysql_version_id >= 50000 ) + { + $ENV{'NDB_EXAMPLES_DIR'}= $path_ndb_examples_dir; + $ENV{'MY_NDB_EXAMPLES_BINARY'}= $exe_ndb_example; + } $ENV{'NDB_EXAMPLES_OUTPUT'}= $path_ndb_testrun_log; } From 0b48fb08c6eb93696bbf909d5646fba7abea9a6c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 17:51:56 -0400 Subject: [PATCH 135/235] Additional patch for 5.1 commit for Bug#14262. sql/sp.cc: Update binlog-writing scheme to 5.1 model. sql/sql_acl.cc: Update binlog-writing scheme to 5.1 model. sql/sql_trigger.cc: Update binlog-writing scheme to 5.1 model. --- sql/sp.cc | 8 ++++---- sql/sql_acl.cc | 28 ++++++++++++++-------------- sql/sql_trigger.cc | 5 ++--- 3 files changed, 20 insertions(+), 21 deletions(-) diff --git a/sql/sp.cc b/sql/sp.cc index dfba2b903bc..fd42ec8e9f2 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -659,8 +659,8 @@ db_drop_routine(THD *thd, int type, sp_name *name) if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } } @@ -704,8 +704,8 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics) if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 66e07c8cf46..aa13c2f08f4 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3146,8 +3146,8 @@ bool mysql_table_grant(THD *thd, TABLE_LIST *table_list, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } } @@ -3312,8 +3312,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } } @@ -3425,8 +3425,8 @@ bool mysql_grant(THD *thd, const char *db, List &list, if (mysql_bin_log.is_open()) { thd->clear_error(); - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } } @@ -5438,8 +5438,8 @@ bool mysql_create_user(THD *thd, List &list) if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } rw_unlock(&LOCK_grant); @@ -5501,8 +5501,8 @@ bool mysql_drop_user(THD *thd, List &list) if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } rw_unlock(&LOCK_grant); @@ -5577,8 +5577,8 @@ bool mysql_rename_user(THD *thd, List &list) if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } rw_unlock(&LOCK_grant); @@ -5758,8 +5758,8 @@ bool mysql_revoke_all(THD *thd, List &list) if (mysql_bin_log.is_open()) { - Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); } rw_unlock(&LOCK_grant); diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index b35e126f2c3..61d2992ed1b 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -284,9 +284,8 @@ end: thd->clear_error(); /* Such a statement can always go directly to binlog, no trans cache. */ - Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0, - FALSE); - mysql_bin_log.write(&qinfo); + thd->binlog_query(THD::MYSQL_QUERY_TYPE, + stmt_query.ptr(), stmt_query.length(), FALSE, FALSE); } } From 99d42667d68a6ad5c52c6a24029477687b44f45d Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 12 Oct 2006 17:10:34 -0600 Subject: [PATCH 136/235] Bug #19764: SHOW commands end up in the slow log as table scans Do not consider SHOW commands slow queries, just because they don't use proper indexes. This bug fix is not needed in 5.1, and the code changes will be null merged. However, the test cases will be propogated up to 5.1. mysql-test/t/show_check-master.opt: Rename: BitKeeper/deleted/.del-show_check-master.opt -> mysql-test/t/show_check-master.opt mysql-test/r/ps.result: Add test case for bug 19764 mysql-test/r/show_check.result: Add test case for bug 19764 mysql-test/r/union.result: Adjust test case results based on bug #19764 changes mysql-test/t/ps.test: Add test case for bug 19764 mysql-test/t/show_check.test: Add test case for bug 19764 sql/sql_parse.cc: Do not log SHOW commands as slow queries just because they don't use indexes. sql/sql_prepare.cc: Save stmt_backup.lex->orig_sql_command for use in log_slow_statement() mysql-test/t/ps-master.opt: Add log-slow-queries and --log-queries-not-using indexes, to test bug #19764 --- mysql-test/r/ps.result | 17 +++++++++++++++++ mysql-test/r/show_check.result | 15 +++++++++++++++ mysql-test/r/union.result | 8 ++++---- mysql-test/t/ps-master.opt | 1 + mysql-test/t/ps.test | 14 ++++++++++++++ mysql-test/t/show_check-master.opt | 1 + mysql-test/t/show_check.test | 12 ++++++++++++ sql/sql_parse.cc | 6 ++++-- sql/sql_prepare.cc | 6 ++++++ 9 files changed, 74 insertions(+), 6 deletions(-) create mode 100644 mysql-test/t/ps-master.opt create mode 100644 mysql-test/t/show_check-master.opt diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 1727c4ddfbe..1d06ff65439 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1358,4 +1358,21 @@ EXECUTE stmt USING @a; i j i i j DEALLOCATE PREPARE stmt; DROP TABLE IF EXISTS t1, t2, t3; +flush status; +prepare sq from 'show status like "slow_queries"'; +execute sq; +Variable_name Value +Slow_queries 0 +prepare no_index from 'select 1 from information_schema.tables limit 1'; +execute sq; +Variable_name Value +Slow_queries 0 +execute no_index; +1 +1 +execute sq; +Variable_name Value +Slow_queries 1 +deallocate prepare no_index; +deallocate prepare sq; End of 5.0 tests. diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 762019be313..1ced624b196 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -630,4 +630,19 @@ SHOW TABLES FROM no_such_database; ERROR 42000: Unknown database 'no_such_database' SHOW COLUMNS FROM no_such_table; ERROR 42S02: Table 'test.no_such_table' doesn't exist +flush status; +show status like 'slow_queries'; +Variable_name Value +Slow_queries 0 +show tables; +Tables_in_test +show status like 'slow_queries'; +Variable_name Value +Slow_queries 0 +select 1 from information_schema.tables limit 1; +1 +1 +show status like 'slow_queries'; +Variable_name Value +Slow_queries 1 End of 5.0 tests diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 12463658bf9..dc174e35c8f 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -836,27 +836,27 @@ count(*) 26 show status like 'Slow_queries'; Variable_name Value -Slow_queries 1 +Slow_queries 0 select count(*) from t1 where b=13; count(*) 10 show status like 'Slow_queries'; Variable_name Value -Slow_queries 3 +Slow_queries 1 select count(*) from t1 where b=13 union select count(*) from t1 where a=7; count(*) 10 26 show status like 'Slow_queries'; Variable_name Value -Slow_queries 5 +Slow_queries 2 select count(*) from t1 where a=7 union select count(*) from t1 where b=13; count(*) 26 10 show status like 'Slow_queries'; Variable_name Value -Slow_queries 7 +Slow_queries 3 flush status; select a from t1 where b not in (1,2,3) union select a from t1 where b not in (4,5,6); a diff --git a/mysql-test/t/ps-master.opt b/mysql-test/t/ps-master.opt new file mode 100644 index 00000000000..3eb98fc3d6b --- /dev/null +++ b/mysql-test/t/ps-master.opt @@ -0,0 +1 @@ +--log-slow-queries --log-long-format --log-queries-not-using-indexes diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index cc239306558..91700fdae95 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -1410,4 +1410,18 @@ DEALLOCATE PREPARE stmt; DROP TABLE IF EXISTS t1, t2, t3; +# +# Bug 19764: SHOW commands end up in the slow log as table scans +# + +flush status; +prepare sq from 'show status like "slow_queries"'; +execute sq; +prepare no_index from 'select 1 from information_schema.tables limit 1'; +execute sq; +execute no_index; +execute sq; +deallocate prepare no_index; +deallocate prepare sq; + --echo End of 5.0 tests. diff --git a/mysql-test/t/show_check-master.opt b/mysql-test/t/show_check-master.opt new file mode 100644 index 00000000000..3eb98fc3d6b --- /dev/null +++ b/mysql-test/t/show_check-master.opt @@ -0,0 +1 @@ +--log-slow-queries --log-long-format --log-queries-not-using-indexes diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 07426193dcf..849be577893 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -507,4 +507,16 @@ SHOW TABLES FROM no_such_database; SHOW COLUMNS FROM no_such_table; +# +# Bug #19764: SHOW commands end up in the slow log as table scans +# +flush status; +show status like 'slow_queries'; +show tables; +show status like 'slow_queries'; +# Table scan query, to ensure that slow_queries does still get incremented +# (mysqld is started with --log-queries-not-using-indexes) +select 1 from information_schema.tables limit 1; +show status like 'slow_queries'; + --echo End of 5.0 tests diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 18d048df393..fdbfa71e141 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2159,9 +2159,11 @@ void log_slow_statement(THD *thd) if ((ulong) (thd->start_time - thd->time_after_lock) > thd->variables.long_query_time || - ((thd->server_status & + (thd->server_status & (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) && - (specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES))) + (specialflag & SPECIAL_LOG_QUERIES_NOT_USING_INDEXES) && + /* == SQLCOM_END unless this is a SHOW command */ + thd->lex->orig_sql_command == SQLCOM_END) { thd->status_var.long_query_count++; mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query); diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 32f0ca6859d..e8025121eb3 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2908,6 +2908,12 @@ bool Prepared_statement::execute(String *expanded_query, bool open_cursor) stmt_backup.query= thd->query; stmt_backup.query_length= thd->query_length; + /* + Save orig_sql_command as we use it to disable slow logging for SHOW + commands (see log_slow_statement()). + */ + stmt_backup.lex->orig_sql_command= thd->lex->orig_sql_command; + /* At first execution of prepared statement we may perform logical transformations of the query tree. Such changes should be performed From e3516186d51cef09051c842e5a8e6a4d19efe00e Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 08:48:47 +0200 Subject: [PATCH 137/235] Add missing semicolon in test file mysql-test/r/csv.result: Update result after add of missing semicolon --- mysql-test/r/csv.result | 3 +-- mysql-test/t/csv.test | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/csv.result b/mysql-test/r/csv.result index 2e3d11ad461..7c7bcc3440c 100644 --- a/mysql-test/r/csv.result +++ b/mysql-test/r/csv.result @@ -4913,8 +4913,7 @@ bonfire Colombo nondecreasing DROP TABLE t1; -ALTER TABLE t2 RENAME t1 -#; +ALTER TABLE t2 RENAME t1; DROP TABLE t1; CREATE TABLE t1 ( Period smallint(4) unsigned zerofill DEFAULT '0000' NOT NULL, diff --git a/mysql-test/t/csv.test b/mysql-test/t/csv.test index 5b693335a43..e78c2ccc578 100644 --- a/mysql-test/t/csv.test +++ b/mysql-test/t/csv.test @@ -1295,7 +1295,7 @@ SELECT fld3 FROM t2; # DROP TABLE t1; -ALTER TABLE t2 RENAME t1 +ALTER TABLE t2 RENAME t1; # # Drop and recreate From a4c972bcf7259063c47ef7213c9f8012ba63d8b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 10:41:40 +0200 Subject: [PATCH 138/235] Improve function that finds the reason why test was skipped, the old version only looked at the ast line, but there might be some additional debug info there so it's better to scan the whole file. There should be only one line that says "reason: " --- mysql-test/mysql-test-run.pl | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dc2212f953b..24cdedce712 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2815,6 +2815,33 @@ sub do_after_run_mysqltest($) } +sub find_testcase_skipped_reason($) +{ + my ($tinfo)= @_; + + # Open mysqltest.log + my $F= IO::File->new($path_timefile) or + mtr_error("can't open file \"$path_timefile\": $!"); + my $reason; + + while ( my $line= <$F> ) + { + # Look for "reason: " + if ( $line =~ /reason: (.*)/ ) + { + $reason= $1; + } + } + + if ( ! $reason ) + { + mtr_warning("Could not find reason for skipping test in $path_timefile"); + $reason= "Detected by testcase(reason unknown) "; + } + $tinfo->{'comment'}= $reason; +} + + ############################################################################## # # Run a single test case @@ -2887,10 +2914,7 @@ sub run_testcase ($) { # Testcase itself tell us to skip this one # Try to get reason from mysqltest.log - my $last_line= mtr_lastlinefromfile($path_timefile) if -f $path_timefile; - my $reason= mtr_match_prefix($last_line, "reason: "); - $tinfo->{'comment'}= - defined $reason ? $reason : "Detected by testcase(reason unknown) "; + find_testcase_skipped_reason($tinfo); mtr_report_test_skipped($tinfo); } elsif ( $res == 63 ) From b35617cdbad6d8b3bb5e162deb4677fd08aaf01d Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 11:05:46 +0200 Subject: [PATCH 139/235] Improve the function that parses test files looking for what features it uses Now also detects "source nnnn;" command, previous version only detected "--source" --- mysql-test/lib/mtr_cases.pl | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index e6980a0abb9..42062b7ba24 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -575,8 +575,6 @@ sub mtr_options_from_test_file($$) { while ( my $line= <$F> ) { - next if ( $line !~ /^--/ ); - # Match this line against tag in "tags" array foreach my $tag (@tags) { @@ -588,14 +586,21 @@ sub mtr_options_from_test_file($$) { } # If test sources another file, open it as well - if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ ) + if ( $line =~ /^\-\-([[:space:]]*)source(.*)$/ or + $line =~ /^([[:space:]]*)source(.*);$/ ) { my $value= $2; $value =~ s/^\s+//; # Remove leading space $value =~ s/[[:space:]]+$//; # Remove ending space my $sourced_file= "$::glob_mysql_test_dir/$value"; - mtr_options_from_test_file($tinfo, $sourced_file); + if ( -f $sourced_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) + mtr_options_from_test_file($tinfo, $sourced_file); + } } } From 851e6fe44e1ba5857db61b89cbec3241956e9367 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 11:38:32 +0200 Subject: [PATCH 140/235] Use 'my_strnncoll_simple' instead of 'strncasecmp' --- client/mysqltest.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 4aa30ba3f1e..e46f22de4df 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3397,8 +3397,10 @@ int read_line(char *buf, int size) DBUG_RETURN(0); } else if ((c == '{' && - (!strncasecmp(buf, "while", min(5, p - buf)) || - !strncasecmp(buf, "if", min(2, p - buf))))) + (!my_strnncoll_simple(charset_info, "while", 5, + buf, min(5, p - buf), 0) || + !my_strnncoll_simple(charset_info, "if", 2, + buf, min(2, p - buf), 0)))) { /* Only if and while commands can be terminated by { */ *p++= c; From be831d7306a0b1537ee1ed48768814c9811f0b39 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 11:53:19 +0200 Subject: [PATCH 141/235] Optimize restarts by using --force-restart option --- mysql-test/t/rpl_dual_pos_advance-master.opt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/rpl_dual_pos_advance-master.opt b/mysql-test/t/rpl_dual_pos_advance-master.opt index 35fcc5f30c6..cef79bc8585 100644 --- a/mysql-test/t/rpl_dual_pos_advance-master.opt +++ b/mysql-test/t/rpl_dual_pos_advance-master.opt @@ -1 +1 @@ ---loose-to-force-a-restart +--force-restart From 60a21d16975de436d57c9e29f237234b71fd5601 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 19:05:54 +0500 Subject: [PATCH 142/235] Fix for bug #23254: COMPRESS(NULL) makes all futher COMPRESS() calls on same Item return NULL We don't set null_value to 0 in the Item_func_compress::val_str() for not-NULL results. mysql-test/r/func_compress.result: Fix for bug #23254: COMPRESS(NULL) makes all futher COMPRESS() calls on same Item return NULL - test result. mysql-test/t/func_compress.test: Fix for bug #23254: COMPRESS(NULL) makes all futher COMPRESS() calls on same Item return NULL - test case. sql/item_strfunc.cc: Fix for bug #23254: COMPRESS(NULL) makes all futher COMPRESS() calls on same Item return NULL - set null_value. --- mysql-test/r/func_compress.result | 10 ++++++++++ mysql-test/t/func_compress.test | 14 +++++++++++++- sql/item_strfunc.cc | 1 + 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index 8d6fa9927ce..ed8d66e9327 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -79,3 +79,13 @@ uncompress(a) uncompressed_length(a) NULL NULL a 1 drop table t1; +create table t1(a blob); +insert into t1 values ('0'), (NULL), ('0'); +select compress(a), compress(a) from t1; +select compress(a) is null from t1; +compress(a) is null +0 +1 +0 +drop table t1; +End of 4.1 tests diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 0f3c3cab307..223a5540f38 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -54,4 +54,16 @@ insert into t1 values(NULL), (compress('a')); select uncompress(a), uncompressed_length(a) from t1; drop table t1; -# End of 4.1 tests +# +# Bug #23254: problem with compress(NULL) +# + +create table t1(a blob); +insert into t1 values ('0'), (NULL), ('0'); +--disable_result_log +select compress(a), compress(a) from t1; +--enable_result_log +select compress(a) is null from t1; +drop table t1; + +--echo End of 4.1 tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 98888226e58..f7408cb5e9f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2838,6 +2838,7 @@ String *Item_func_compress::val_str(String *str) null_value= 1; return 0; } + null_value= 0; if (res->is_empty()) return res; /* From 665e557533c707a8fc6d9ac66a8bd446682112c7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 10:57:50 -0400 Subject: [PATCH 143/235] Merge fix-up. vio/viossl.c: We prefer "0x%lx" to "%p". --- sql/sql_view.cc | 15 ++++++++++++++- vio/viossl.c | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index a3e0f6b1e5a..82acab7129e 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -573,6 +573,19 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, } append_identifier(thd, &buff, views->table_name, views->table_name_length); + if (lex->view_list.elements) + { + List_iterator_fast names(lex->view_list); + LEX_STRING *name; + int i; + + for (i= 0; name= names++; i++) + { + buff.append(i ? ", " : "("); + append_identifier(thd, &buff, name->str, name->length); + } + buff.append(')'); + } buff.append(STRING_WITH_LEN(" AS ")); buff.append(views->source.str, views->source.length); @@ -1378,7 +1391,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) error= TRUE; query_cache_invalidate3(thd, view, 0); sp_cache_invalidate(); - + } if (mysql_bin_log.is_open()) { thd->clear_error(); diff --git a/vio/viossl.c b/vio/viossl.c index e869493c604..090b837b972 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -82,7 +82,7 @@ int vio_ssl_read(Vio *vio, gptr buf, int size) { int r; DBUG_ENTER("vio_ssl_read"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d, ssl_: 0x%p", + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d, ssl_: 0x%lx", vio->sd, buf, size, vio->ssl_arg)); r= SSL_read((SSL*) vio->ssl_arg, buf, size); @@ -99,7 +99,7 @@ int vio_ssl_write(Vio *vio, const gptr buf, int size) { int r; DBUG_ENTER("vio_ssl_write"); - DBUG_PRINT("enter", ("sd: %d, buf: 0x%p, size: %d", vio->sd, buf, size)); + DBUG_PRINT("enter", ("sd: %d, buf: 0x%lx, size: %d", vio->sd, buf, size)); r= SSL_write((SSL*) vio->ssl_arg, buf, size); #ifndef DBUG_OFF From 7e73af6342bd436fc505084f868ec19378b79d5c Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 20:22:56 +0200 Subject: [PATCH 144/235] rpl_empty_master_crash need a master restart so that all log files are deleted mysql-test/t/rpl_empty_master_crash-master.opt: New BitKeeper file ``mysql-test/t/rpl_empty_master_crash-master.opt'' --- mysql-test/t/rpl_empty_master_crash-master.opt | 1 + 1 file changed, 1 insertion(+) create mode 100644 mysql-test/t/rpl_empty_master_crash-master.opt diff --git a/mysql-test/t/rpl_empty_master_crash-master.opt b/mysql-test/t/rpl_empty_master_crash-master.opt new file mode 100644 index 00000000000..cef79bc8585 --- /dev/null +++ b/mysql-test/t/rpl_empty_master_crash-master.opt @@ -0,0 +1 @@ +--force-restart From 00e327ed88a9cecd683a3fa3ec393b6be9f43854 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 13 Oct 2006 20:29:27 +0200 Subject: [PATCH 145/235] Look for client bindirs client_release and client_debug before other directories. --- mysql-test/mysql-test-run.pl | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 24cdedce712..3cc0110ed05 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -468,11 +468,11 @@ sub initial_setup () { # # Look for the path where to find the client binaries - $path_client_bindir= mtr_path_exists("$glob_basedir/client/release", + $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", + "$glob_basedir/client_debug", + "$glob_basedir/client/release", "$glob_basedir/client/debug", "$glob_basedir/client", - "$glob_basedir/client_release", - "$glob_basedir/client_debug", "$glob_basedir/bin"); # Look for the mysqld executable @@ -484,6 +484,7 @@ sub initial_setup () { "$path_client_bindir/mysqld-debug", "$path_client_bindir/mysqld-max", "$glob_basedir/libexec/mysqld", + "$glob_basedir/bin/mysqld", "$glob_basedir/sql/release/mysqld", "$glob_basedir/sql/debug/mysqld"); From 0d9e6366a82b5e9a8606ac332aeacc5cb9c54923 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Oct 2006 16:31:20 +0200 Subject: [PATCH 146/235] Skip looking for mysql_client_test in 4.1 on windows as it's not built by default --- mysql-test/mysql-test-run.pl | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3cc0110ed05..79f01c3cb68 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1417,18 +1417,27 @@ sub executable_setup () { } - # Look for mysql_client_test executable - if ( $glob_use_embedded_server ) + if ( $glob_win32 and $mysql_version_id < 50000 ) { - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); + # Skip looking for exe_mysql_client_test as its not built by default + # in 4.1 for windows. + exe_mysql_client_test= "unavailable"; } else { - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test", - "$glob_basedir/tests/release/mysql_client_test", - "$glob_basedir/tests/debug/mysql_client_test"); + # Look for mysql_client_test executable + if ( $glob_use_embedded_server ) + { + $exe_mysql_client_test= + mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); + } + else + { + $exe_mysql_client_test= + mtr_exe_exists("$glob_basedir/tests/mysql_client_test", + "$glob_basedir/tests/release/mysql_client_test", + "$glob_basedir/tests/debug/mysql_client_test"); + } } } From b0a4ec859faaf985d9e28fa443af9316729843be Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Oct 2006 17:02:43 +0200 Subject: [PATCH 147/235] Improving debugging support in 'read_line' function --- client/mysqltest.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index e46f22de4df..7029e0af3e1 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3346,7 +3346,7 @@ int read_line(char *buf, int size) LINT_INIT(last_quote); start_lineno= cur_file->lineno; - DBUG_PRINT("info", ("start_lineno: %d", start_lineno)); + DBUG_PRINT("info", ("Starting to read at lineno: %d", start_lineno)); for (; p < buf_end ;) { skip_char= 0; @@ -3370,7 +3370,7 @@ int read_line(char *buf, int size) die("Missing end of block"); *p= 0; - DBUG_PRINT("info", ("end of file")); + DBUG_PRINT("info", ("end of file at line %d", cur_file->lineno)); DBUG_RETURN(1); } cur_file--; @@ -3393,7 +3393,8 @@ int read_line(char *buf, int size) if (end_of_query(c)) { *p= 0; - DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_PRINT("exit", ("Found delimiter '%s' at line %d", + delimiter, cur_file->lineno)); DBUG_RETURN(0); } else if ((c == '{' && @@ -3405,7 +3406,8 @@ int read_line(char *buf, int size) /* Only if and while commands can be terminated by { */ *p++= c; *p= 0; - DBUG_PRINT("exit", ("Found '{' indicating begining of block")); + DBUG_PRINT("exit", ("Found '{' indicating start of block at line %d", + cur_file->lineno)); DBUG_RETURN(0); } else if (c == '\'' || c == '"' || c == '`') @@ -3420,7 +3422,8 @@ int read_line(char *buf, int size) { /* Comments are terminated by newline */ *p= 0; - DBUG_PRINT("exit", ("Found newline in comment")); + DBUG_PRINT("exit", ("Found newline in comment at line: %d", + cur_file->lineno)); DBUG_RETURN(0); } break; @@ -3435,13 +3438,19 @@ int read_line(char *buf, int size) { /* Skip all space at begining of line */ if (c == '\n') - start_lineno= cur_file->lineno; /* Query hasn't started yet */ + { + /* Query hasn't started yet */ + start_lineno= cur_file->lineno; + DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d", + start_lineno)); + } skip_char= 1; } else if (end_of_query(c)) { *p= 0; - DBUG_PRINT("exit", ("Found delimiter '%s'", delimiter)); + DBUG_PRINT("exit", ("Found delimiter '%s' at line: %d", + delimiter, cur_file->lineno)); DBUG_RETURN(0); } else if (c == '}') @@ -3449,7 +3458,8 @@ int read_line(char *buf, int size) /* A "}" need to be by itself in the begining of a line to terminate */ *p++= c; *p= 0; - DBUG_PRINT("exit", ("Found '}' in begining of a line")); + DBUG_PRINT("exit", ("Found '}' in begining of a line at line: %d", + cur_file->lineno)); DBUG_RETURN(0); } else if (c == '\'' || c == '"' || c == '`') From 8ec4020e2534e7b26721bb07c89d77eb11482c77 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Oct 2006 17:09:06 +0200 Subject: [PATCH 148/235] Use char as datatype for the byte that are read with my_fgetc, fixes problem with mysqltest.test on Solaris and Mac. write_file produced nice files with all zeroes. client/mysqltest.c: Use char as datatype for the byte that are read with my_fgetc mysql-test/mysql-test-run.pl: Fix typo, add missing $ --- client/mysqltest.c | 2 +- mysql-test/mysql-test-run.pl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 7029e0af3e1..efb5f1915f4 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1810,7 +1810,7 @@ void my_ungetc(int c) void read_until_delimiter(DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_delimiter) { - int c; + char c; DBUG_ENTER("read_until_delimiter"); DBUG_PRINT("enter", ("delimiter: %s, length: %d", ds_delimiter->str, ds_delimiter->length)); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 79f01c3cb68..35782733b20 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1421,7 +1421,7 @@ sub executable_setup () { { # Skip looking for exe_mysql_client_test as its not built by default # in 4.1 for windows. - exe_mysql_client_test= "unavailable"; + $exe_mysql_client_test= "unavailable"; } else { From ad4d813024b6e6ec8e0b9f0796f2a304edf218e2 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 14 Oct 2006 17:14:03 +0200 Subject: [PATCH 149/235] No need to continue in 'mtr_report_test_failed' after timeout detected, return immediately after --- mysql-test/lib/mtr_report.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index ec1bed9671b..b173896d48a 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -133,6 +133,7 @@ sub mtr_report_test_failed ($) { if ( $tinfo->{'timeout'} ) { print "[ fail ] timeout\n"; + return; } elsif ( $tinfo->{'ndb_test'} and $::cluster->[0]->{'installed_ok'} eq "NO") { From b8177c3ead885fc6925e7b0fb8ac3c96e974570b Mon Sep 17 00:00:00 2001 From: unknown Date: Sun, 15 Oct 2006 15:38:56 +0200 Subject: [PATCH 150/235] Cleanup mtr_timer Add verbose printouts making it possible to see what happens. Make it an error if trying to stop a non existing timer Print warning if fork fails. --- mysql-test/lib/mtr_timer.pl | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl index a85ab8c6122..4c71e41fa0a 100644 --- a/mysql-test/lib/mtr_timer.pl +++ b/mysql-test/lib/mtr_timer.pl @@ -4,23 +4,22 @@ # and is part of the translation of the Bourne shell script with the # same name. -use Carp qw(cluck); use Socket; use Errno; use strict; #use POSIX ":sys_wait_h"; -use POSIX 'WNOHANG'; +#use POSIX 'WNOHANG'; sub mtr_init_timers (); sub mtr_timer_start($$$); sub mtr_timer_stop($$); sub mtr_timer_stop_all($); -sub mtr_timer_waitpid($$$); + ############################################################################## # -# Initiate a structure shared by all timers +# Initiate the structure shared by all timers # ############################################################################## @@ -35,17 +34,19 @@ sub mtr_init_timers () { # Start, stop and poll a timer # # As alarm() isn't portable to Windows, we use separate processes to -# implement timers. That is why there is a mtr_timer_waitpid(), as this -# is where we catch a timeout. +# implement timers. # ############################################################################## sub mtr_timer_start($$$) { my ($timers,$name,$duration)= @_; + mtr_verbose("mtr_timer_start: $name, $duration"); + if ( exists $timers->{'timers'}->{$name} ) { # We have an old running timer, kill it + mtr_verbose("There is an old timer running"); mtr_timer_stop($timers,$name); } @@ -57,7 +58,7 @@ sub mtr_timer_start($$$) { { if ( $! == $!{EAGAIN} ) # See "perldoc Errno" { - mtr_debug("Got EAGAIN from fork(), sleep 1 second and redo"); + mtr_warning("Got EAGAIN from fork(), sleep 1 second and redo"); sleep(1); redo FORK; } @@ -70,6 +71,7 @@ sub mtr_timer_start($$$) { if ( $tpid ) { # Parent, record the information + mtr_verbose("timer parent, record info($name, $tpid, $duration)"); $timers->{'timers'}->{$name}->{'pid'}= $tpid; $timers->{'timers'}->{$name}->{'duration'}= $duration; $timers->{'pids'}->{$tpid}= $name; @@ -85,6 +87,7 @@ sub mtr_timer_start($$$) { $SIG{INT}= 'DEFAULT'; $0= "mtr_timer(timers,$name,$duration)"; + mtr_verbose("timer child $name, sleep $duration"); sleep($duration); exit(0); } @@ -95,9 +98,12 @@ sub mtr_timer_start($$$) { sub mtr_timer_stop ($$) { my ($timers,$name)= @_; + mtr_verbose("mtr_timer_stop: $name"); + if ( exists $timers->{'timers'}->{$name} ) { my $tpid= $timers->{'timers'}->{$name}->{'pid'}; + mtr_verbose("Stopping timer with pid $tpid"); # FIXME as Cygwin reuses pids fast, maybe check that is # the expected process somehow?! @@ -114,7 +120,7 @@ sub mtr_timer_stop ($$) { } else { - mtr_debug("Asked to stop timer \"$name\" not started"); + mtr_error("Asked to stop timer \"$name\" not started"); return 0; } } From 46d7f12fca9e097d75df52ec877fc9e3f4fdfb58 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 16 Oct 2006 18:36:33 +0200 Subject: [PATCH 151/235] yassl build fixes for hpux and netware extra/yassl/include/yassl_int.hpp: Netware and HPUX need the _POSIX_THREADS define to be forced extra/yassl/taocrypt/include/hmac.hpp: Prefix with HMAC as we get symbol conflicts on HPUX --- extra/yassl/include/yassl_int.hpp | 7 +++++++ extra/yassl/taocrypt/include/hmac.hpp | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index 28e9d237622..0edff289b61 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -40,6 +40,13 @@ #include "lock.hpp" #include "openssl/ssl.h" // ASN1_STRING and DH +// Check if _POSIX_THREADS should be forced +#if !defined(_POSIX_THREADS) && (defined(__NETWARE__) || defined(__hpux)) +// HPUX does not define _POSIX_THREADS as it's not _fully_ implemented +// Netware supports pthreads but does not announce it +#define _POSIX_THREADS +#endif + #ifdef _POSIX_THREADS #include #endif diff --git a/extra/yassl/taocrypt/include/hmac.hpp b/extra/yassl/taocrypt/include/hmac.hpp index d46a6d4e7c3..b710c3aa499 100644 --- a/extra/yassl/taocrypt/include/hmac.hpp +++ b/extra/yassl/taocrypt/include/hmac.hpp @@ -60,12 +60,12 @@ private: T mac_; // MSVC 6 HACK, gives compiler error if calculated in array - enum { BSIZE = T::BLOCK_SIZE / sizeof(word32), - DSIZE = T::DIGEST_SIZE / sizeof(word32) }; + enum { HMAC_BSIZE = T::BLOCK_SIZE / sizeof(word32), + HMAC_DSIZE = T::DIGEST_SIZE / sizeof(word32) }; - word32 ip_[BSIZE]; // align ipad_ on word32 - word32 op_[BSIZE]; // align opad_ on word32 - word32 innerH_[DSIZE]; // align innerHash_ on word32 + word32 ip_[HMAC_BSIZE]; // align ipad_ on word32 + word32 op_[HMAC_BSIZE]; // align opad_ on word32 + word32 innerH_[HMAC_DSIZE]; // align innerHash_ on word32 void KeyInnerHash(); From dd5edc0aaa6280f3c4e514f4050a388ad4b870e4 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Oct 2006 08:10:51 +0200 Subject: [PATCH 152/235] When calculating what features to use for _this_ test run, don't look at test that already are deterined to be skipped --- mysql-test/mysql-test-run.pl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 35782733b20..5309e030c2c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -391,6 +391,8 @@ sub main () { my ($need_ndbcluster,$need_im); foreach my $test (@$tests) { + next if $test->{skip}; + $need_ndbcluster||= $test->{ndb_test}; $need_im||= $test->{component_id} eq 'im'; From 40ac968926f4aefbe0cab4cb971cf3fb512bb38f Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Oct 2006 10:31:06 +0200 Subject: [PATCH 153/235] Remove warnings Set comment properly before calling mtr_report_test failed and report_failure_restart mysql-test/lib/mtr_report.pl: Remove warnings No need to check ndb installed ok here, when that is detected comment is set to indicate the problem --- mysql-test/lib/mtr_report.pl | 7 +------ mysql-test/mysql-test-run.pl | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 20 deletions(-) diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index b173896d48a..e92cac5cfba 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -130,16 +130,11 @@ sub mtr_report_test_failed ($) { my $tinfo= shift; $tinfo->{'result'}= 'MTR_RES_FAILED'; - if ( $tinfo->{'timeout'} ) + if ( defined $tinfo->{'timeout'} ) { print "[ fail ] timeout\n"; return; } - elsif ( $tinfo->{'ndb_test'} and $::cluster->[0]->{'installed_ok'} eq "NO") - { - print "[ fail ] ndbcluster start failure\n"; - return; - } else { print "[ fail ]\n"; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5309e030c2c..1d217bdef84 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2755,10 +2755,9 @@ sub run_testcase_check_skip_test($) # If test needs this cluster, check it was installed ok if ( !$cluster->{'installed_ok'} ) { - mtr_tofile($path_timefile, - "Test marked as failed because $cluster->{'name'} " . - "was not installed ok!"); mtr_report_test_name($tinfo); + $tinfo->{comment}= + "Cluster $cluster->{'name'} was not installed ok"; mtr_report_test_failed($tinfo); return 1; } @@ -2881,10 +2880,8 @@ sub run_testcase ($) { # Can't restart a running server that may be in use if ( $glob_use_running_server ) { - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Can't restart a running server"; - mtr_report_test_name($tinfo); + $tinfo->{comment}= "Can't restart a running server"; mtr_report_test_skipped($tinfo); return; } @@ -2934,16 +2931,16 @@ sub run_testcase ($) { $tinfo->{'timeout'}= 1; # Mark as timeout report_failure_and_restart($tinfo); } + elsif ( $res == 1 ) + { + # Test case failure reported by mysqltest + report_failure_and_restart($tinfo); + } else { - # Test case failed, if in control mysqltest returns 1 - if ( $res != 1 ) - { - mtr_tofile($path_timefile, - "mysqltest returned unexpected code $res, " . - "it has probably crashed"); - } - + # mysqltest failed, probably crashed + $tinfo->{comment}= + "mysqltest returned unexpected code $res, it has probably crashed"; report_failure_and_restart($tinfo); } From 48dfeb4de0e3444fe5ddf9aba1040707d11cfa85 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Oct 2006 11:06:11 -0400 Subject: [PATCH 154/235] Fix previous bad patch for Bug#14262. Remove table engine qualification where it's unnecessary. mysql-test/r/view.result: Remove requirement for innodb where not needed. (Running this test alone raised warnings that it was using myisam.) mysql-test/t/view.test: Remove requirement for innodb where not needed. (Running this test alone raised warnings that it was using myisam.) sql/sql_parse.cc: Fix previous bad re-patch. sql/sql_view.cc: Fix previous bad re-patch. --- mysql-test/r/view.result | 4 ++-- mysql-test/t/view.test | 4 ++-- sql/sql_parse.cc | 2 ++ sql/sql_view.cc | 1 - 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 213a1dcde20..d71f046d095 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -1980,7 +1980,7 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI drop view v1; drop table t1; set sql_mode='strict_all_tables'; -CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB; +CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL); CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1; CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2; INSERT INTO t1 (col1) VALUES(12); @@ -2032,7 +2032,7 @@ f3 f1 1 3 drop view v1; drop table t1; -CREATE TABLE t1 (f1 char) ENGINE = innodb; +CREATE TABLE t1 (f1 char); INSERT INTO t1 VALUES ('A'); CREATE VIEW v1 AS SELECT * FROM t1; INSERT INTO t1 VALUES('B'); diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index b631d2032c4..f53f5c1d46c 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1801,7 +1801,7 @@ drop table t1; # underlying tables (BUG#6443) # set sql_mode='strict_all_tables'; -CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL) ENGINE = INNODB; +CREATE TABLE t1 (col1 INT NOT NULL, col2 INT NOT NULL); CREATE VIEW v1 (vcol1) AS SELECT col1 FROM t1; CREATE VIEW v2 (vcol1) AS SELECT col1 FROM t1 WHERE col2 > 2; -- error 1364 @@ -1857,7 +1857,7 @@ drop table t1; # # Test for bug #11771: wrong query_id in SELECT * FROM # -CREATE TABLE t1 (f1 char) ENGINE = innodb; +CREATE TABLE t1 (f1 char); INSERT INTO t1 VALUES ('A'); CREATE VIEW v1 AS SELECT * FROM t1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index febe256807a..e0b870e7381 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4720,6 +4720,8 @@ end_with_restore_list: { if (end_active_trans(thd)) goto error; + + res= mysql_create_view(thd, first_table, thd->lex->create_view_mode); break; } case SQLCOM_DROP_VIEW: diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 82acab7129e..245ef1a9f54 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1384,7 +1384,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) non_existant_views.append(','); non_existant_views.append(String(view->table_name,system_charset_info)); } - VOID(pthread_mutex_unlock(&LOCK_open)); continue; } if (my_delete(path, MYF(MY_WME))) From 099d87419e897aaac1088bee57e523ae8b6b23d3 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Oct 2006 12:15:14 -0600 Subject: [PATCH 155/235] Update ps and show_check results to account for new -master.opt settings. mysql-test/r/ps.result: Update test results to account for new ps-master.opt settings mysql-test/r/show_check.result: Update test results to account for new show_check-master.opt settings --- mysql-test/r/ps.result | 31 ++++++++++++++++++++------- mysql-test/r/show_check.result | 38 ++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 7dadb3207a8..0d9c108a2bf 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1537,54 +1537,62 @@ flush tables; show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 call proc_1(); show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 call proc_1(); show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 call proc_1(); show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 flush tables; create function func_1() returns int begin flush tables; return 1; end| ERROR 0A000: FLUSH is not allowed in stored function or trigger @@ -1600,49 +1608,56 @@ select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 prepare abc from "flush tables"; execute abc; show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 execute abc; show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 execute abc; show open tables from mysql; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 select Host, User from mysql.user limit 0; Host User select Host, Db from mysql.host limit 0; Host Db show open tables from mysql; Database Table In_use Name_locked -mysql user 0 0 mysql general_log 1 0 +mysql slow_log 1 0 mysql host 0 0 +mysql user 0 0 flush tables; deallocate prepare abc; create procedure proc_1() flush logs; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 3836148faa9..7a1ef7cedcf 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -148,12 +148,14 @@ flush tables; show open tables; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 create table t1(n int); insert into t1 values (1); show open tables; Database Table In_use Name_locked -test t1 0 0 mysql general_log 1 0 +mysql slow_log 1 0 +test t1 0 0 drop table t1; create table t1 (a int not null, b VARCHAR(10), INDEX (b) ) AVG_ROW_LENGTH=10 CHECKSUM=1 COMMENT="test" ENGINE=MYISAM MIN_ROWS=10 MAX_ROWS=100 PACK_KEYS=1 DELAY_KEY_WRITE=1 ROW_FORMAT=fixed; show create table t1; @@ -566,21 +568,23 @@ SELECT 1 FROM mysql.db, mysql.proc, mysql.user, mysql.time_zone, mysql.time_zone 1 SHOW OPEN TABLES; Database Table In_use Name_locked -mysql db 0 0 +mysql proc 0 0 test urkunde 0 0 mysql time_zone 0 0 -mysql general_log 1 0 +mysql db 0 0 test txt1 0 0 -mysql proc 0 0 +mysql slow_log 1 0 test tyt2 0 0 +mysql general_log 1 0 mysql user 0 0 mysql time_zone_name 0 0 SHOW OPEN TABLES FROM mysql; Database Table In_use Name_locked -mysql db 0 0 -mysql time_zone 0 0 -mysql general_log 1 0 mysql proc 0 0 +mysql time_zone 0 0 +mysql db 0 0 +mysql slow_log 1 0 +mysql general_log 1 0 mysql user 0 0 mysql time_zone_name 0 0 SHOW OPEN TABLES FROM mysql LIKE 'u%'; @@ -594,14 +598,16 @@ test tyt2 0 0 mysql time_zone_name 0 0 SHOW OPEN TABLES LIKE '%o%'; Database Table In_use Name_locked -mysql time_zone 0 0 -mysql general_log 1 0 mysql proc 0 0 +mysql time_zone 0 0 +mysql slow_log 1 0 +mysql general_log 1 0 mysql time_zone_name 0 0 FLUSH TABLES; SHOW OPEN TABLES; Database Table In_use Name_locked mysql general_log 1 0 +mysql slow_log 1 0 DROP TABLE txt1; DROP TABLE tyt2; DROP TABLE urkunde; @@ -674,20 +680,20 @@ SHOW COLUMNS FROM no_such_table; ERROR 42S02: Table 'test.no_such_table' doesn't exist flush status; show status like 'slow_queries'; -Variable_name Value -Slow_queries 0 +Variable_name Value +Slow_queries 0 show tables; Tables_in_test show status like 'slow_queries'; -Variable_name Value -Slow_queries 0 +Variable_name Value +Slow_queries 1 select 1 from information_schema.tables limit 1; 1 1 show status like 'slow_queries'; -Variable_name Value -Slow_queries 1 -End of 5.0 tests +Variable_name Value +Slow_queries 2 +End of 5.0 tests. SHOW AUTHORS; create database mysqltest; show create database mysqltest; From dfa183b7a7c0cf323d44700fac57c19e5fc17f44 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 17 Oct 2006 16:22:44 -0400 Subject: [PATCH 156/235] Merge fixes. mysql-test/r/func_time.result: One update from errmsg.txt and removal of /two/ duplicate results. mysql-test/t/func_time.test: Removed duplicate test. --- mysql-test/r/func_time.result | 26 +------------------------- mysql-test/t/func_time.test | 18 ------------------ 2 files changed, 1 insertion(+), 43 deletions(-) diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index e5b4b6bd5e6..037b1ca9df7 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -892,18 +892,6 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1) + 0` double(23,6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; -SET NAMES latin1; -SET character_set_results = NULL; -SHOW VARIABLES LIKE 'character_set_results'; -Variable_name Value -character_set_results -CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); -INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); -SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; -fmtddate field2 -Sep-4 12:00AM abcd -DROP TABLE testBug8868; -SET NAMES DEFAULT; SELECT SEC_TO_TIME(3300000); SEC_TO_TIME(3300000) 838:59:59 @@ -981,7 +969,7 @@ CREATE TABLE t1(f1 TIME); INSERT INTO t1 VALUES('916:00:00 a'); Warnings: Warning 1265 Data truncated for column 'f1' at row 1 -Warning 1264 Out of range value adjusted for column 'f1' at row 1 +Warning 1264 Out of range value for column 'f1' at row 1 SELECT * FROM t1; f1 838:59:59 @@ -1023,18 +1011,6 @@ union (select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H); H 5 -SET NAMES latin1; -SET character_set_results = NULL; -SHOW VARIABLES LIKE 'character_set_results'; -Variable_name Value -character_set_results -CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); -INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); -SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; -fmtddate field2 -Sep-4 12:00AM abcd -DROP TABLE testBug8868; -SET NAMES DEFAULT; End of 4.1 tests explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, timestampdiff(SQL_TSI_FRAC_SECOND, '2001-02-01 12:59:59.120000', '2001-05-01 12:58:58.119999') as a2; diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 6e0a313e834..d331c363926 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -525,24 +525,6 @@ union union (select time_format(timediff(now(), DATE_SUB(now(),INTERVAL 5 HOUR)),'%k') As H); -# -# 21913: DATE_FORMAT() Crashes mysql server if I use it through -# mysql-connector-j driver. -# - -SET NAMES latin1; -SET character_set_results = NULL; -SHOW VARIABLES LIKE 'character_set_results'; - -CREATE TABLE testBug8868 (field1 DATE, field2 VARCHAR(32) CHARACTER SET BINARY); -INSERT INTO testBug8868 VALUES ('2006-09-04', 'abcd'); - -SELECT DATE_FORMAT(field1,'%b-%e %l:%i%p') as fmtddate, field2 FROM testBug8868; - -DROP TABLE testBug8868; - -SET NAMES DEFAULT; - --echo End of 4.1 tests explain extended select timestampdiff(SQL_TSI_WEEK, '2001-02-01', '2001-05-01') as a1, From 85cfdc5bcc38cf0e17dde5857f482146d1c34b51 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 13:24:06 +0200 Subject: [PATCH 157/235] Make --with-ndbcluster only be valid together with --bench Improve code that detects if ndb shuold be installed Remove call to stop_all_servers after install db, if any servers are still running and need to be stopped they will be stopped atuomatically mysql-test/lib/mtr_cases.pl: All tests that have "source include/have_ndb.inc" are ndb tests mysql-test/mysql-test-run.pl: Set --with-ndbcluster to only be valid together with --bench Rename opt_ndbcluster_supported to glob_ndbcluster_supported it's not an option Fix warnings --- mysql-test/lib/mtr_cases.pl | 81 +++++++++++++++++++----------------- mysql-test/mysql-test-run.pl | 50 ++++++++++++---------- 2 files changed, 71 insertions(+), 60 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 42062b7ba24..88c51728fb2 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -59,7 +59,9 @@ sub collect_test_cases ($) { if ( @::opt_cases ) { - foreach my $tname ( @::opt_cases ) { # Run in specified order, no sort + foreach my $tname ( @::opt_cases ) + { + # Run in specified order, no sort my $elem= undef; my $component_id= undef; @@ -85,7 +87,7 @@ sub collect_test_cases ($) { # If target component is known, check that the specified test case # exists. - # + # # Otherwise, try to guess the target component. if ( $component_id ) @@ -127,7 +129,8 @@ sub collect_test_cases ($) { } else { - foreach my $elem ( sort readdir(TESTDIR) ) { + foreach my $elem ( sort readdir(TESTDIR) ) + { my $component_id= undef; my $tname= undef; @@ -144,7 +147,9 @@ sub collect_test_cases ($) { next; } - next if $::opt_do_test and ! defined mtr_match_prefix($elem,$::opt_do_test); + # Skip tests that does not match the --do-test= filter + next if $::opt_do_test and + ! defined mtr_match_prefix($elem,$::opt_do_test); collect_one_test_case($testdir,$resdir,$tname,$elem,$cases,\%disabled, $component_id); @@ -152,7 +157,7 @@ sub collect_test_cases ($) { closedir TESTDIR; } - # Reorder the test cases in an order that wil make them faster to run + # Reorder the test cases in an order that will make them faster to run if ( $::opt_reorder ) { @@ -306,40 +311,6 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'slave_num'}= 1; } - if ( $::opt_with_ndbcluster or defined mtr_match_substring($tname,"ndb") ) - { - # This is an ndb test or all tests should be run with ndb cluster started - $tinfo->{'ndb_test'}= 1; - if ( ! $::opt_ndbcluster_supported ) - { - # Ndb is not supported, skip them - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster support"; - return; - } - elsif ( $::opt_skip_ndbcluster ) - { - # All ndb test's should be skipped - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)"; - return; - } - } - else - { - # This is not a ndb test - $tinfo->{'ndb_test'}= 0; - if ( $::opt_with_ndbcluster_only ) - { - # Only the ndb test should be run, all other should be skipped - $tinfo->{'skip'}= 1; - $tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)"; - return; - } - } - - # FIXME what about embedded_server + ndbcluster, skip ?! - my $master_opt_file= "$testdir/$tname-master.opt"; my $slave_opt_file= "$testdir/$tname-slave.opt"; my $slave_mi_file= "$testdir/$tname.slave-mi"; @@ -550,6 +521,37 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'comment'}= "Test need debug binaries"; return; } + + if ( $tinfo->{'ndb_test'} ) + { + # This is a NDB test + if ( ! $::glob_ndbcluster_supported ) + { + # Ndb is not supported, skip it + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No ndbcluster support"; + return; + } + elsif ( $::opt_skip_ndbcluster ) + { + # All ndb test's should be skipped + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No ndbcluster tests(--skip-ndbcluster)"; + return; + } + } + else + { + # This is not a ndb test + if ( $::opt_with_ndbcluster_only ) + { + # Only the ndb test should be run, all other should be skipped + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "Only ndbcluster tests(--with-ndbcluster-only)"; + return; + } + } + } } @@ -563,6 +565,7 @@ our @tags= ["include/have_binlog_format_statement.inc", "binlog_format", "stmt"], ["include/big_test.inc", "big_test", 1], ["include/have_debug.inc", "need_debug", 1], + ["include/have_ndb.inc", "ndb_test", 1], ["include/have_ndb_extra.inc", "ndb_extra", 1], ["require_manager", "require_manager", 1], ); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1d217bdef84..05baaaa6f2f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -65,6 +65,7 @@ use IO::Socket; use IO::Socket::INET; use Data::Dumper; use strict; +use warnings; use diagnostics; our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl @@ -277,7 +278,7 @@ our $opt_skip_ndbcluster= 0; our $opt_skip_ndbcluster_slave= 0; our $opt_with_ndbcluster= 0; our $opt_with_ndbcluster_only= 0; -our $opt_ndbcluster_supported= 0; +our $glob_ndbcluster_supported= 0; our $opt_ndb_extra_test= 0; our $opt_skip_master_binlog= 0; our $opt_skip_slave_binlog= 0; @@ -572,10 +573,10 @@ sub command_line_setup () { 'compress' => \$opt_compress, 'bench' => \$opt_bench, 'small-bench' => \$opt_small_bench, + 'with-ndbcluster' => \$opt_with_ndbcluster, # Control what test suites or cases to run 'force' => \$opt_force, - 'with-ndbcluster' => \$opt_with_ndbcluster, 'with-ndbcluster-only' => \$opt_with_ndbcluster_only, 'skip-ndbcluster|skip-ndb' => \$opt_skip_ndbcluster, 'skip-ndbcluster-slave|skip-ndb-slave' @@ -846,9 +847,9 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Ndb cluster flags # -------------------------------------------------------------------------- - if ( $opt_with_ndbcluster and $opt_skip_ndbcluster) + if ( $opt_with_ndbcluster and !$opt_bench) { - mtr_error("Can't specify both --with-ndbcluster and --skip-ndbcluster"); + mtr_error("Can only use --with-ndbcluster togheter with --bench"); } if ( $opt_ndbconnectstring ) @@ -1485,7 +1486,7 @@ sub environment_setup () { # -------------------------------------------------------------------------- # Add the path where libndbclient can be found # -------------------------------------------------------------------------- - if ( $opt_ndbcluster_supported ) + if ( $glob_ndbcluster_supported ) { push(@ld_library_paths, "$glob_basedir/storage/ndb/src/.libs"); } @@ -1870,6 +1871,8 @@ sub cleanup_stale_files () { rmtree(readlink($opt_vardir)); # Remove the entire "var" dir rmtree("$opt_vardir/"); + # Remove the "var" symlink + unlink($opt_vardir); } else { @@ -2042,7 +2045,7 @@ sub check_ndbcluster_support ($) { $opt_skip_ndbcluster_slave= 1; return; } - $opt_ndbcluster_supported= 1; + $glob_ndbcluster_supported= 1; mtr_report("Using ndbcluster when necessary, mysqld supports it"); if ( $mysql_version_id < 50100 ) @@ -2059,11 +2062,6 @@ sub check_ndbcluster_support ($) { sub ndbcluster_start_install ($) { my $cluster= shift; - if ( $opt_skip_ndbcluster or $glob_use_running_ndbcluster ) - { - return 0; - } - mtr_report("Installing $cluster->{'name'} Cluster"); mkdir($cluster->{'data_dir'}); @@ -2477,11 +2475,24 @@ sub mysql_install_db () { my $cluster_started_ok= 1; # Assume it can be started - if (ndbcluster_start_install($clusters->[0]) || - ($max_slave_num && !$opt_skip_ndbcluster_slave && - ndbcluster_start_install($clusters->[1]))) + if ($opt_skip_ndbcluster || $glob_use_running_ndbcluster) { - mtr_warning("Failed to start install of cluster"); + # Don't install master cluster + } + elsif (ndbcluster_start_install($clusters->[0])) + { + mtr_warning("Failed to start install of $clusters->[0]->{name}"); + $cluster_started_ok= 0; + } + + if ($max_slave_num == 0 || + $opt_skip_ndbcluster_slave || $glob_use_running_ndbcluster_slave) + { + # Don't install slave cluster + } + elsif (ndbcluster_start_install($clusters->[1])) + { + mtr_warning("Failed to start install of $clusters->[1]->{name}"); $cluster_started_ok= 0; } @@ -2514,9 +2525,6 @@ sub mysql_install_db () { } } - # Stop clusters... - stop_all_servers(); - return 0; } @@ -3592,14 +3600,14 @@ sub run_testcase_need_master_restart($) mtr_verbose("Restart master: Restart forced with --force-restart"); } elsif ( ! $opt_skip_ndbcluster and - $tinfo->{'ndb_test'} == 0 and + !$tinfo->{'ndb_test'} and $clusters->[0]->{'pid'} != 0 ) { $do_restart= 1; # Restart without cluster mtr_verbose("Restart master: Test does not need cluster"); } elsif ( ! $opt_skip_ndbcluster and - $tinfo->{'ndb_test'} == 1 and + $tinfo->{'ndb_test'} and $clusters->[0]->{'pid'} == 0 ) { $do_restart= 1; # Restart with cluster @@ -4455,6 +4463,7 @@ Options to control what engine/variation to run skip-ssl Dont start server with support for ssl connections bench Run the benchmark suite small-bench Run the benchmarks with --small-tests --small-tables + with-ndbcluster Use cluster as default table type for benchmark Options to control directories to use benchdir=DIR The directory where the benchmark suite is stored @@ -4471,7 +4480,6 @@ Options to control directories to use Options to control what test suites or cases to run force Continue to run the suite after failure - with-ndbcluster Use cluster in all tests with-ndbcluster-only Run only tests that include "ndb" in the filename skip-ndb[cluster] Skip all tests that need cluster skip-ndb[cluster]-slave Skip all tests that need a slave cluster From b860c4dbf5b7255e6052084cb4514589a5d24619 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 16:30:51 +0200 Subject: [PATCH 158/235] Fix bug where a timer was stopped by calling mtr_timer_stop with a "timer" instead of it's name --- mysql-test/lib/mtr_timer.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl index 4c71e41fa0a..9bb37c7e3fc 100644 --- a/mysql-test/lib/mtr_timer.pl +++ b/mysql-test/lib/mtr_timer.pl @@ -144,7 +144,7 @@ sub mtr_timer_timeout ($$) { # We got a timeout my $name= $timers->{'pids'}->{$pid}; - mtr_timer_stop($timers, $timers->{'timers'}->{$name}); + mtr_timer_stop($timers, $name); return $name; } From 8e5b64ae0ad99070d93cb491c8f0aba5c889709e Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 16:39:00 +0200 Subject: [PATCH 159/235] Stop all timers before exiting when --start-and-exit --- mysql-test/mysql-test-run.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 05baaaa6f2f..daa5b8aca96 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2913,6 +2913,7 @@ sub run_testcase ($) { # ---------------------------------------------------------------------- if ( $opt_start_and_exit or $opt_start_dirty ) { + mtr_timer_stop_all($glob_timers); mtr_report("\nServers started, exiting"); exit(0); } From 62309faa1d478faf836da3d71b1a92b3c5ffdf61 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 16:40:22 +0200 Subject: [PATCH 160/235] Remove some junk --- mysql-test/lib/mtr_process.pl | 2 -- mysql-test/lib/mtr_timer.pl | 3 --- 2 files changed, 5 deletions(-) diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 2831c179ea5..affe8278376 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -8,7 +8,6 @@ use Socket; use Errno; use strict; -#use POSIX ":sys_wait_h"; use POSIX 'WNOHANG'; sub mtr_run ($$$$$$;$); @@ -1088,7 +1087,6 @@ sub mtr_kill_processes ($) { sub mtr_exit ($) { my $code= shift; -# cluck("Called mtr_exit()"); mtr_timer_stop_all($::glob_timers); local $SIG{HUP} = 'IGNORE'; # ToDo: Signalling -$$ will only work if we are the process group diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl index 9bb37c7e3fc..406692e35fa 100644 --- a/mysql-test/lib/mtr_timer.pl +++ b/mysql-test/lib/mtr_timer.pl @@ -8,9 +8,6 @@ use Socket; use Errno; use strict; -#use POSIX ":sys_wait_h"; -#use POSIX 'WNOHANG'; - sub mtr_init_timers (); sub mtr_timer_start($$$); sub mtr_timer_stop($$); From 3c0a746633122920b4fa2c42d2f64176d7e71333 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 17:16:08 +0200 Subject: [PATCH 161/235] Don't stop the time in mtr_timer_timeout, that will be done after testcase or when program exit --- mysql-test/lib/mtr_timer.pl | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/mysql-test/lib/mtr_timer.pl b/mysql-test/lib/mtr_timer.pl index 406692e35fa..06374716c62 100644 --- a/mysql-test/lib/mtr_timer.pl +++ b/mysql-test/lib/mtr_timer.pl @@ -139,10 +139,8 @@ sub mtr_timer_timeout ($$) { return "" unless exists $timers->{'pids'}->{$pid}; - # We got a timeout - my $name= $timers->{'pids'}->{$pid}; - mtr_timer_stop($timers, $name); - return $name; + # We got a timeout, return the name ot the timer + return $timers->{'pids'}->{$pid}; } 1; From ea80f1a07a009ec9ee8097ea885f2fcd44495107 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 17:58:26 +0200 Subject: [PATCH 162/235] =?UTF-8?q?Put=20the=20printf=20of=20failed=20rati?= =?UTF-8?q?o=20on=20it=C3=A4s=20only=20line,=20printf=20was=20tricked=20in?= =?UTF-8?q?to=20thinking=20the=20escaped=20%=20+=20w=20was=20a=20format=20?= =?UTF-8?q?specifier?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mysql-test/lib/mtr_report.pl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mysql-test/lib/mtr_report.pl b/mysql-test/lib/mtr_report.pl index e92cac5cfba..8d7de9d1a4b 100644 --- a/mysql-test/lib/mtr_report.pl +++ b/mysql-test/lib/mtr_report.pl @@ -203,8 +203,9 @@ sub mtr_report_stats ($) { else { my $ratio= $tot_passed * 100 / $tot_tests; - printf "Failed $tot_failed/$tot_tests tests, " . - "%.2f\% were successful.\n\n", $ratio; + print "Failed $tot_failed/$tot_tests tests, "; + printf("%.2f", $ratio); + print "\% were successful.\n\n"; print "The log files in var/log may give you some hint\n", "of what went wrong.\n", From 1fb887361d3fe899a4c7af37ecc216a4ca707992 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 18:17:41 +0200 Subject: [PATCH 163/235] Fix for bug#23379 "wrong time value in SHOW PROCESSLIST" The value taken to be shown in SHOW PROCESSLIST is not initialized when THD is created and will be random for unauthenticated connections. To the documentor: Random value, instead of NULL, was shown, in SHOW PROCESSLIST for still non-authenticated connections. sql/sql_class.cc: Initialize time_after_lock. It is used from SHOW PROCESSLIST's code. If not initialized random value is shown for connected but still unauthenticated clients in the column Time. --- sql/sql_class.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index da752977fcd..f18f2fb6b7c 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -181,6 +181,7 @@ THD::THD() // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; start_time=(time_t) 0; + time_after_lock=(time_t) 0; current_linfo = 0; slave_thread = 0; variables.pseudo_thread_id= 0; From 8008bf9faa6d4abf8a0a312341b07ca6a6fb64d0 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 22:47:30 +0200 Subject: [PATCH 164/235] Remove extra whitespace in result file mysql-test/r/show_check.result: Remove extra whitespace --- mysql-test/r/show_check.result | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index 1ced624b196..28cbdb16919 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -632,17 +632,17 @@ SHOW COLUMNS FROM no_such_table; ERROR 42S02: Table 'test.no_such_table' doesn't exist flush status; show status like 'slow_queries'; -Variable_name Value -Slow_queries 0 +Variable_name Value +Slow_queries 0 show tables; Tables_in_test show status like 'slow_queries'; -Variable_name Value -Slow_queries 0 +Variable_name Value +Slow_queries 0 select 1 from information_schema.tables limit 1; 1 1 show status like 'slow_queries'; -Variable_name Value -Slow_queries 1 +Variable_name Value +Slow_queries 1 End of 5.0 tests From 016a7d4c636de66246f443eade4a76ac75b52173 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 18:43:51 -0400 Subject: [PATCH 165/235] Bug#19745: mysqldump --xml produces invalid xml The mysqldump command with both the --xml and --hex-blob options will output blob data encoded as hexBinary. The proper XML datatype is xs:hexBinary. The correct XML datatype is specified be setting the xsi_type attribute equal to xs:hexBinary for each encoded element. client/mysqldump.c: Bug#19745: mysqldump --xml produces invalid xml - Moved hex-blob code to it's own function. - Rewrote print_xml_tag function to accept zero or more attribute/value pair(s) which are appended to a separate tag name. - --xml option respects the --hex-blob option by ouputting blob data in hex encoded format. Each hex encoded field tag will also contain an xsi:type attribute with an xs:hexBinary value. - --extended-insert and --xml are mutually exclusive. Otherwise, the xml file will contain INSERT commands. - Minor comment cleanup. mysql-test/r/mysqldump.result: Bug#19745: mysqldump --xml produces invalid xml -Added results. mysql-test/t/mysqldump.test: Bug#19745: mysqldump --xml produces invalid xml -Added test. --- client/mysqldump.c | 134 +++++++++++++++++++++++++--------- mysql-test/r/mysqldump.result | 22 ++++++ mysql-test/t/mysqldump.test | 15 ++++ 3 files changed, 135 insertions(+), 36 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index b3a209c6086..5929cde6af6 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -45,6 +45,7 @@ #include #include #include +#include #include "client_priv.h" #include "mysql.h" @@ -523,6 +524,8 @@ static void write_header(FILE *sql_file, char *db_name) if (opt_xml) { fputs("\n", sql_file); + /* Schema reference. Allows use of xsi:nil for NULL values and + xsi:type to define an element's data type. */ fputs("send + Print XML tag with any number of attribute="value" pairs to the xml_file. + + Format is: + sbegsend NOTE - sval MUST be a NULL terminated string. - sval string will be qouted before output. + Additional arguments must be present in attribute/value pairs. + The last argument should be the null character pointer. + All attribute_value arguments MUST be NULL terminated strings. + All attribute_value arguments will be quoted before output. */ -static void print_xml_tag1(FILE * xml_file, const char* sbeg, - const char* stag_atr, const char* sval, - const char* send) +static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send, + const char* tag_name, + const char* first_attribute_name, ...) { + va_list arg_list; + char *attribute_name, *attribute_value; + fputs(sbeg, xml_file); - fputs("<", xml_file); - fputs(stag_atr, xml_file); - fputs("\"", xml_file); - print_quoted_xml(xml_file, sval, strlen(sval)); - fputs("\">", xml_file); + fputc('<', xml_file); + fputs(tag_name, xml_file); + + va_start(arg_list, first_attribute_name); + attribute_name= first_attribute_name; + while (attribute_name != NullS) + { + attribute_value= va_arg(arg_list, char *); + DBUG_ASSERT(attribute_value != NullS); + + fputc(' ', xml_file); + fputs(attribute_name, xml_file); + fputc('\"', xml_file); + + print_quoted_xml(xml_file, attribute_value, strlen(attribute_value)); + fputc('\"', xml_file); + + attribute_name= va_arg(arg_list, char *); + } + va_end(arg_list); + + fputc('>', xml_file); fputs(send, xml_file); check_io(xml_file); } @@ -1270,6 +1302,28 @@ static void print_xml_row(FILE *xml_file, const char *row_name, check_io(xml_file); } +/* + Print hex value for blob data. + + SYNOPSIS + print_blob_as_hex() + output_file - output file + str - string to print + len - its length + + DESCRIPTION + Print hex value for blob data. +*/ + +static void print_blob_as_hex(FILE *output_file, const char *str, ulong len) +{ + /* sakaik got the idea to to provide blob's in hex notation. */ + char *ptr= str, *end= ptr + len; + for (; ptr < end ; ptr++) + fprintf(output_file, "%02X", *((uchar *)ptr)); + check_io(output_file); +} + /* dump_routines_for_db -- retrievs list of routines for a given db, and prints out @@ -1714,7 +1768,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (!opt_xml) fprintf(sql_file, "CREATE TABLE %s (\n", result_table); else - print_xml_tag1(sql_file, "\t", "table_structure name=", table, "\n"); + print_xml_tag(sql_file, "\t", "\n", "table_structure", "name=", table, + NullS); check_io(sql_file); } @@ -2283,8 +2338,8 @@ static void dump_table(char *table, char *db) rownr=0; init_length=(uint) insert_pat.length+4; if (opt_xml) - print_xml_tag1(md_result_file, "\t", "table_data name=", table, "\n"); - + print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table, + NullS); if (opt_autocommit) { fprintf(md_result_file, "set autocommit=0;\n"); @@ -2338,7 +2393,7 @@ static void dump_table(char *table, char *db) field->type == MYSQL_TYPE_LONG_BLOB || field->type == MYSQL_TYPE_MEDIUM_BLOB || field->type == MYSQL_TYPE_TINY_BLOB)) ? 1 : 0; - if (extended_insert) + if (extended_insert && !opt_xml) { if (i == 0) dynstr_set(&extended_row,"("); @@ -2427,18 +2482,25 @@ static void dump_table(char *table, char *db) { if (opt_xml) { - print_xml_tag1(md_result_file, "\t\t", "field name=", - field->name, ""); - print_quoted_xml(md_result_file, row[i], length); + if (opt_hex_blob && is_blob && length) + { + /* Define xsi:type="xs:hexBinary" for hex encoded data */ + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, "xsi:type=", "xs:hexBinary", NullS); + print_blob_as_hex(md_result_file, row[i], length); + } + else + { + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, NullS); + print_quoted_xml(md_result_file, row[i], length); + } fputs("\n", md_result_file); } else if (opt_hex_blob && is_blob && length) { - /* sakaik got the idea to to provide blob's in hex notation. */ - char *ptr= row[i], *end= ptr + length; fputs("0x", md_result_file); - for (; ptr < end ; ptr++) - fprintf(md_result_file, "%02X", *((uchar *)ptr)); + print_blob_as_hex(md_result_file, row[i], length); } else unescape(md_result_file, row[i], length); @@ -2449,8 +2511,8 @@ static void dump_table(char *table, char *db) char *ptr= row[i]; if (opt_xml) { - print_xml_tag1(md_result_file, "\t\t", "field name=", - field->name, ""); + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, NullS); fputs(!my_isalpha(charset_info, *ptr) ? ptr: "NULL", md_result_file); fputs("\n", md_result_file); @@ -2781,7 +2843,7 @@ static int dump_all_tables_in_db(char *database) if (init_dumping(database, init_dumping_tables)) return 1; if (opt_xml) - print_xml_tag1(md_result_file, "", "database name=", database, "\n"); + print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS); if (lock_tables) { DYNAMIC_STRING query; @@ -2858,7 +2920,7 @@ static my_bool dump_all_views_in_db(char *database) if (init_dumping(database, init_dumping_views)) return 1; if (opt_xml) - print_xml_tag1(md_result_file, "", "database name=", database, "\n"); + print_xml_tag(md_result_file, "", "\n", "database", "name=", database, NullS); if (lock_tables) { DYNAMIC_STRING query; @@ -2997,7 +3059,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) /* We shall countinue here, if --force was given */ } if (opt_xml) - print_xml_tag1(md_result_file, "", "database name=", db, "\n"); + print_xml_tag(md_result_file, "", "\n", "database", "name=", db, NullS); /* Dump each selected table */ for (pos= dump_tables; pos < end; pos++) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index ee50fc42203..54583febbc8 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3196,5 +3196,27 @@ UNLOCK TABLES; DROP TABLE `t1`; # +# Bug #19745: mysqldump --xml produces invalid xml +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); +INSERT INTO t1 VALUES(1,0xff00fef0); + + + + + + + + + + 1 + FF00FEF0 + + + + +DROP TABLE t1; +# # End of 5.0 tests # diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 6dfb24c2e75..72aad395ec0 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1412,6 +1412,21 @@ insert into t1 values (0815, 4711, 2006); DROP TABLE `t1`; --enable_warnings +--echo # +--echo # Bug #19745: mysqldump --xml produces invalid xml +--echo # + +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings + +CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); +INSERT INTO t1 VALUES(1,0xff00fef0); + +--exec $MYSQL_DUMP --xml --hex-blob --skip-create-options test t1 + +DROP TABLE t1; + --echo # --echo # End of 5.0 tests --echo # From 54fadc5b88824886d34242f2fd871c856a8f006b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 00:53:01 +0200 Subject: [PATCH 166/235] Change the ssl related variables to loose so they work also when the server is compiled without ssl --- mysql-test/t/ssl_des-master.opt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/ssl_des-master.opt b/mysql-test/t/ssl_des-master.opt index b610fe3f250..0b2b8cb85ac 100644 --- a/mysql-test/t/ssl_des-master.opt +++ b/mysql-test/t/ssl_des-master.opt @@ -1 +1 @@ ---ssl-cert=std_data/server-cert-des.pem --ssl-key=std_data/server-key-des.pem +--loose_ssl-cert=std_data/server-cert-des.pem --loose_ssl-key=std_data/server-key-des.pem From 2b238773fa728d1fc125cd548b01b273687c8cec Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 18 Oct 2006 19:17:56 -0400 Subject: [PATCH 167/235] Post-Merge Fix. --- mysql-test/r/mysqldump.result | 45 +++++++++++++++++------------------ 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 3be6111a65f..54c68701f78 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -3195,6 +3195,28 @@ UNLOCK TABLES; DROP TABLE `t1`; # +# Bug #19745: mysqldump --xml produces invalid xml +# +DROP TABLE IF EXISTS t1; +CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); +INSERT INTO t1 VALUES(1,0xff00fef0); + + + + + + + + + + 1 + FF00FEF0 + + + + +DROP TABLE t1; +# # End of 5.0 tests # drop table if exists t1; @@ -3235,29 +3257,6 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; DROP TABLE t1; -# Bug #19745: mysqldump --xml produces invalid xml -# -DROP TABLE IF EXISTS t1; -CREATE TABLE t1 (f1 int(10), data MEDIUMBLOB); -INSERT INTO t1 VALUES(1,0xff00fef0); - - - - - - - - - - 1 - FF00FEF0 - - - - -DROP TABLE t1; -# -# End of 5.0 tests create table t1 (a text , b text); create table t2 (a text , b text); insert t1 values ("Duck, Duck", "goose"); From da7af481cda9d0fb836f010d421ce00830b69f56 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 12:52:37 +0500 Subject: [PATCH 168/235] Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes We miss some records sometimes using RANGE method if we have partial key segments. Example: Create table t1(a char(2), key(a(1))); insert into t1 values ('a'), ('xx'); select a from t1 where a > 'x'; We call index_read() passing 'x' key and HA_READ_AFTER_KEY flag in the handler::read_range_first() wich is wrong because we have a partial key segment for the field and might miss records like 'xx'. Fix: don't use open segments in such a case. mysql-test/r/range.result: Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes - test result. mysql-test/t/range.test: Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes - test case. sql/opt_range.cc: Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes - check if we have a partial key segment for a Item_func::GT_FUNC; if so, don't set NEAR_MIN flag in order to use HA_READ_KEY_OR_NEXT instead of HA_READ_AFTER_KEY. sql/opt_range.h: Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes - key segment 'flag' slot added. sql/sql_select.cc: Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes - test (HA_PART_KEY_SEG | HA_NULL_PART) as we split it in the sql/table.cc sql/table.cc: Fix for bug #20732: Partial index and long sjis search with '>' fails sometimes - set HA_NULL_PART flag instead of HA_PART_KEY_SEG in order not to mix them. --- mysql-test/r/range.result | 10 ++++++++++ mysql-test/t/range.test | 12 +++++++++++- sql/opt_range.cc | 6 +++++- sql/opt_range.h | 2 +- sql/sql_select.cc | 2 +- sql/table.cc | 2 +- 6 files changed, 29 insertions(+), 5 deletions(-) diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result index b436519d967..f25d94f8066 100644 --- a/mysql-test/r/range.result +++ b/mysql-test/r/range.result @@ -649,3 +649,13 @@ OR ((pk4 =1) AND (((pk1 IN ( 7, 2, 1 ))) OR (pk1 =522)) AND ((pk2 IN ( 0, 2635)) pk1 pk2 pk3 pk4 filler 2621 2635 1000015 0 filler drop table t1, t2; +create table t1(a char(2), key(a(1))); +insert into t1 values ('x'), ('xx'); +explain select a from t1 where a > 'x'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range a a 2 NULL 2 Using where +select a from t1 where a > 'x'; +a +xx +drop table t1; +End of 4.1 tests diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test index 9280911df2c..245178d7d4a 100644 --- a/mysql-test/t/range.test +++ b/mysql-test/t/range.test @@ -510,4 +510,14 @@ OR ((pk4 =1) AND (((pk1 IN ( 7, 2, 1 ))) OR (pk1 =522)) AND ((pk2 IN ( 0, 2635)) ) AND (pk3 >=1000000); drop table t1, t2; -# End of 4.1 tests +# +# Bug #20732: Partial index and long sjis search with '>' fails sometimes +# + +create table t1(a char(2), key(a(1))); +insert into t1 values ('x'), ('xx'); +explain select a from t1 where a > 'x'; +select a from t1 where a > 'x'; +drop table t1; + +--echo End of 4.1 tests diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 6b129997e47..06e42ff363f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -885,6 +885,7 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, key_parts->null_bit= key_part_info->null_bit; key_parts->image_type = (key_info->flags & HA_SPATIAL) ? Field::itMBR : Field::itRAW; + key_parts->flag= key_part_info->key_part_flag; } param.real_keynr[param.keys++]=idx; } @@ -1398,7 +1399,9 @@ get_mm_leaf(PARAM *param, COND *conf_func, Field *field, KEY_PART *key_part, } break; case Item_func::GT_FUNC: - if (field_is_equal_to_item(field,value)) + /* Don't use open ranges for partial key_segments */ + if (field_is_equal_to_item(field,value) && + !(key_part->flag & HA_PART_KEY_SEG)) tree->min_flag=NEAR_MIN; /* fall through */ case Item_func::GE_FUNC: @@ -2899,6 +2902,7 @@ QUICK_SELECT *get_quick_select_for_ref(THD *thd, TABLE *table, TABLE_REF *ref) key_part->length= key_info->key_part[part].length; key_part->store_length= key_info->key_part[part].store_length; key_part->null_bit= key_info->key_part[part].null_bit; + key_part->flag= key_info->key_part[part].key_part_flag; } if (quick->ranges.push_back(range)) goto err; diff --git a/sql/opt_range.h b/sql/opt_range.h index 367a85dc6f2..4d425604921 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -36,7 +36,7 @@ typedef struct st_key_part { uint16 key,part, store_length, length; - uint8 null_bit; + uint8 null_bit, flag; Field *field; Field::imagetype image_type; } KEY_PART; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 33e923e1553..009cd7ae283 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -7337,7 +7337,7 @@ part_of_refkey(TABLE *table,Field *field) for (uint part=0 ; part < ref_parts ; part++,key_part++) if (field->eq(key_part->field) && - !(key_part->key_part_flag & HA_PART_KEY_SEG)) + !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART))) return table->reginfo.join_tab->ref.items[part]; } return (Item*) 0; diff --git a/sql/table.cc b/sql/table.cc index 0efed04c06e..f99afa61db9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -676,7 +676,7 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, as we need to test for NULL = NULL. */ if (field->real_maybe_null()) - key_part->key_part_flag|= HA_PART_KEY_SEG; + key_part->key_part_flag|= HA_NULL_PART; } else { // Error: shorten key From f30cb12707435923a98987f133709bb7bf1f8841 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 10:54:23 +0200 Subject: [PATCH 169/235] Backport test cases fixes from 5.0 client/mysqldump.c: fflush stderr after printing of error message mysql-test/include/have_lowercase0.inc: Remove extra ; mysql-test/r/rpl000015.result: Update result mysql-test/r/rpl_change_master.result: Update result mysql-test/r/rpl_error_ignored_table.result: Update result mysql-test/r/rpl_loaddata.result: Update result mysql-test/r/rpl_log.result: Update result mysql-test/r/rpl_max_relay_size.result: Update result mysql-test/r/rpl_replicate_do.result: Update result mysql-test/t/lowercase_table3.test: Backport from 5.0 mysql-test/t/mysql_protocols.test: Backport from 5.0 mysql-test/t/rpl000015.test: Backport from 5.0 mysql-test/t/rpl_change_master.test: Backport from 5.0 mysql-test/t/rpl_drop_db.test: Backport from 5.0 mysql-test/t/rpl_error_ignored_table.test: Backport from 5.0 mysql-test/t/rpl_loaddata.test: Backport from 5.0 mysql-test/t/rpl_log-master.opt: Use --force-restart command in master.opt to force a restart for this test case mysql-test/t/rpl_log.test: Backport from 5.0 mysql-test/t/rpl_max_relay_size.test: Backport from 5.0 mysql-test/t/rpl_replicate_do.test: Backport from 5.0 --- client/mysqldump.c | 1 + mysql-test/include/have_lowercase0.inc | 4 +-- mysql-test/r/rpl000015.result | 6 ++-- mysql-test/r/rpl_change_master.result | 2 +- mysql-test/r/rpl_error_ignored_table.result | 2 +- mysql-test/r/rpl_loaddata.result | 6 ++-- mysql-test/r/rpl_log.result | 2 +- mysql-test/r/rpl_max_relay_size.result | 36 ++++++++++----------- mysql-test/r/rpl_replicate_do.result | 2 +- mysql-test/t/lowercase_table3.test | 8 ++--- mysql-test/t/mysql_protocols.test | 2 ++ mysql-test/t/rpl000015.test | 8 ++--- mysql-test/t/rpl_change_master.test | 3 +- mysql-test/t/rpl_drop_db.test | 2 ++ mysql-test/t/rpl_error_ignored_table.test | 2 +- mysql-test/t/rpl_loaddata.test | 6 ++-- mysql-test/t/rpl_log-master.opt | 2 +- mysql-test/t/rpl_log.test | 2 +- mysql-test/t/rpl_max_relay_size.test | 12 +++---- mysql-test/t/rpl_replicate_do.test | 2 +- 20 files changed, 56 insertions(+), 54 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 7e15a5dbbad..2d2fe439f76 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -785,6 +785,7 @@ static void DBerror(MYSQL *mysql, const char *when) DBUG_ENTER("DBerror"); fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname, mysql_errno(mysql), mysql_error(mysql), when); + fflush(stderr); safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; } /* DBerror */ diff --git a/mysql-test/include/have_lowercase0.inc b/mysql-test/include/have_lowercase0.inc index f967c18928b..8d3ae02f61e 100644 --- a/mysql-test/include/have_lowercase0.inc +++ b/mysql-test/include/have_lowercase0.inc @@ -1,4 +1,4 @@ --require r/lowercase0.require ---disable_query_log; +--disable_query_log show variables like "lower_case_%"; ---enable_query_log; +--enable_query_log diff --git a/mysql-test/r/rpl000015.result b/mysql-test/r/rpl000015.result index 8cbbe3ab0e8..b3e6ef71e45 100644 --- a/mysql-test/r/rpl000015.result +++ b/mysql-test/r/rpl000015.result @@ -8,16 +8,16 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File change master to master_host='127.0.0.1'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 test MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 test MASTER_PORT 7 4 # # No No 0 0 0 # None 0 No # change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 7 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 7 4 # # No No 0 0 0 # None 0 No # start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 7 master-bin.000001 79 slave-relay-bin.000001 123 master-bin.000001 Yes Yes 0 0 79 123 None 0 No # +# 127.0.0.1 root MASTER_PORT 7 master-bin.000001 79 # # master-bin.000001 Yes Yes 0 0 79 # None 0 No # drop table if exists t1; create table t1 (n int); insert into t1 values (10),(45),(90); diff --git a/mysql-test/r/rpl_change_master.result b/mysql-test/r/rpl_change_master.result index a6342d47b49..16e14f5da2e 100644 --- a/mysql-test/r/rpl_change_master.result +++ b/mysql-test/r/rpl_change_master.result @@ -20,7 +20,7 @@ Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File change master to master_user='root'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 214 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 214 4 None 0 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 214 # # master-bin.000001 No No 0 0 214 # None 0 No # select release_lock("a"); release_lock("a") 1 diff --git a/mysql-test/r/rpl_error_ignored_table.result b/mysql-test/r/rpl_error_ignored_table.result index 789ca72cd61..740d139b4c8 100644 --- a/mysql-test/r/rpl_error_ignored_table.result +++ b/mysql-test/r/rpl_error_ignored_table.result @@ -9,7 +9,7 @@ insert into t1 values (1),(1); ERROR 23000: Duplicate entry '1' for key 1 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 213 slave-relay-bin.000002 257 master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 213 257 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 213 # # master-bin.000001 Yes Yes test.t3,test.t1,test.t2 0 0 213 # None 0 No # show tables like 't1'; Tables_in_test (t1) drop table t1; diff --git a/mysql-test/r/rpl_loaddata.result b/mysql-test/r/rpl_loaddata.result index d0f2a885dcd..446b7961578 100644 --- a/mysql-test/r/rpl_loaddata.result +++ b/mysql-test/r/rpl_loaddata.result @@ -33,7 +33,7 @@ set global sql_slave_skip_counter=1; start slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1311 slave-relay-bin.000002 1355 master-bin.000001 Yes Yes 0 0 1311 1355 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1311 # # master-bin.000001 Yes Yes 0 0 1311 # None 0 No # set sql_log_bin=0; delete from t1; set sql_log_bin=1; @@ -43,7 +43,7 @@ change master to master_user='test'; change master to master_user='root'; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1419 slave-relay-bin.000001 4 master-bin.000001 No No 0 0 1419 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1419 # # master-bin.000001 No No 0 0 1419 # None 0 No # set global sql_slave_skip_counter=1; start slave; set sql_log_bin=0; @@ -54,7 +54,7 @@ stop slave; reset slave; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 4 slave-relay-bin.000001 4 No No 0 0 0 4 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 4 # # No No 0 0 0 # None 0 No # reset master; create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), unique(day)); diff --git a/mysql-test/r/rpl_log.result b/mysql-test/r/rpl_log.result index c496f3d540a..5a351ea693c 100644 --- a/mysql-test/r/rpl_log.result +++ b/mysql-test/r/rpl_log.result @@ -96,7 +96,7 @@ slave-bin.000002 62 Query 1 62 use `test`; insert into t1 values (1) slave-bin.000002 122 Query 1 122 use `test`; drop table t1 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 slave-relay-bin.000003 214 master-bin.000002 Yes Yes 0 0 276 214 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000002 276 # # master-bin.000002 Yes Yes 0 0 276 # None 0 No # show binlog events in 'slave-bin.000005' from 4; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log create table t1(a int auto_increment primary key, b int); diff --git a/mysql-test/r/rpl_max_relay_size.result b/mysql-test/r/rpl_max_relay_size.result index c0a7a0a5b00..eee655adea0 100644 --- a/mysql-test/r/rpl_max_relay_size.result +++ b/mysql-test/r/rpl_max_relay_size.result @@ -28,8 +28,8 @@ Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos 50477 -Relay_Log_File slave-relay-bin.000014 -Relay_Log_Pos 1221 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -43,7 +43,7 @@ Last_Errno 0 Last_Error Skip_Counter 0 Exec_Master_Log_Pos 50477 -Relay_Log_Space 1221 +Relay_Log_Space # Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -71,8 +71,8 @@ Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos 50477 -Relay_Log_File slave-relay-bin.000004 -Relay_Log_Pos 9457 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -86,7 +86,7 @@ Last_Errno 0 Last_Error Skip_Counter 0 Exec_Master_Log_Pos 50477 -Relay_Log_Space 9457 +Relay_Log_Space # Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -114,8 +114,8 @@ Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos 50477 -Relay_Log_File slave-relay-bin.000008 -Relay_Log_Pos 1283 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -129,7 +129,7 @@ Last_Errno 0 Last_Error Skip_Counter 0 Exec_Master_Log_Pos 50477 -Relay_Log_Space 1283 +Relay_Log_Space # Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -154,8 +154,8 @@ Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File Read_Master_Log_Pos 4 -Relay_Log_File slave-relay-bin.000001 -Relay_Log_Pos 4 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File Slave_IO_Running No Slave_SQL_Running No @@ -169,7 +169,7 @@ Last_Errno 0 Last_Error Skip_Counter 0 Exec_Master_Log_Pos 0 -Relay_Log_Space 4 +Relay_Log_Space # Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -195,8 +195,8 @@ Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos 50535 -Relay_Log_File slave-relay-bin.000009 -Relay_Log_Pos 62 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -210,7 +210,7 @@ Last_Errno 0 Last_Error Skip_Counter 0 Exec_Master_Log_Pos 50535 -Relay_Log_Space 62 +Relay_Log_Space # Until_Condition None Until_Log_File Until_Log_Pos 0 @@ -234,8 +234,8 @@ Master_Port MASTER_PORT Connect_Retry 1 Master_Log_File master-bin.000001 Read_Master_Log_Pos 50583 -Relay_Log_File slave-relay-bin.000010 -Relay_Log_Pos 52 +Relay_Log_File # +Relay_Log_Pos # Relay_Master_Log_File master-bin.000001 Slave_IO_Running Yes Slave_SQL_Running Yes @@ -249,7 +249,7 @@ Last_Errno 0 Last_Error Skip_Counter 0 Exec_Master_Log_Pos 50583 -Relay_Log_Space 52 +Relay_Log_Space # Until_Condition None Until_Log_File Until_Log_Pos 0 diff --git a/mysql-test/r/rpl_replicate_do.result b/mysql-test/r/rpl_replicate_do.result index 45ef6cb9b7b..b9294c9c767 100644 --- a/mysql-test/r/rpl_replicate_do.result +++ b/mysql-test/r/rpl_replicate_do.result @@ -28,7 +28,7 @@ ERROR 42S02: Table 'test.t11' doesn't exist drop table if exists t1,t2,t11; show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1340 slave-relay-bin.000002 1384 master-bin.000001 Yes Yes test.t1 0 0 1340 1384 None 0 No # +# 127.0.0.1 root MASTER_PORT 1 master-bin.000001 1340 # # master-bin.000001 Yes Yes test.t1 0 0 1340 # None 0 No # create table t1 (ts timestamp); set one_shot time_zone='met'; insert into t1 values('2005-08-12 00:00:00'); diff --git a/mysql-test/t/lowercase_table3.test b/mysql-test/t/lowercase_table3.test index 549bd7d8045..bf48710d4a6 100644 --- a/mysql-test/t/lowercase_table3.test +++ b/mysql-test/t/lowercase_table3.test @@ -5,12 +5,8 @@ # --source include/have_innodb.inc ---require r/lowercase0.require -disable_query_log; -show variables like "lower_case_%"; ---require r/true.require -select convert(@@version_compile_os using latin1) NOT IN ("NT","WIN2000","Win95/Win98","XP") as "TRUE"; -enable_query_log; +--source include/have_lowercase0.inc +--source include/not_windows.inc --disable_warnings DROP TABLE IF EXISTS t1,T1; diff --git a/mysql-test/t/mysql_protocols.test b/mysql-test/t/mysql_protocols.test index 0253c2b5d17..5eba780420c 100644 --- a/mysql-test/t/mysql_protocols.test +++ b/mysql-test/t/mysql_protocols.test @@ -1,5 +1,7 @@ # Embedded server doesn't support external clients --source include/not_embedded.inc +# Windows does not have SOCKET, but will try to create a PIPE as well as MEMORY +--source include/not_windows.inc # test for Bug #4998 "--protocol doesn't reject bad values" diff --git a/mysql-test/t/rpl000015.test b/mysql-test/t/rpl000015.test index a9520676e1e..4e329fc87ea 100644 --- a/mysql-test/t/rpl000015.test +++ b/mysql-test/t/rpl000015.test @@ -7,24 +7,24 @@ save_master_pos; connection slave; reset slave; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; change master to master_host='127.0.0.1'; # The following needs to be cleaned up when change master is fixed --replace_result $MASTER_MYPORT MASTER_PORT $MYSQL_TCP_PORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; --replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$MASTER_MYPORT; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; connection master; --disable_warnings diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test index befc469e7b5..e7ae798b1a7 100644 --- a/mysql-test/t/rpl_change_master.test +++ b/mysql-test/t/rpl_change_master.test @@ -12,11 +12,12 @@ connection slave; stop slave; select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_column 1 # 8 # 9 # 23 # 33 # --replace_column 1 # 33 # show slave status; change master to master_user='root'; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # Will restart from after the values(2), which is bug select release_lock("a"); diff --git a/mysql-test/t/rpl_drop_db.test b/mysql-test/t/rpl_drop_db.test index 61354198c83..98afc6e3d02 100644 --- a/mysql-test/t/rpl_drop_db.test +++ b/mysql-test/t/rpl_drop_db.test @@ -13,6 +13,7 @@ insert into mysqltest1.t1 values (1); select * from mysqltest1.t1 into outfile 'mysqltest1/f1.txt'; create table mysqltest1.t2 (n int); create table mysqltest1.t3 (n int); +--replace_result \\ / --error 1010 drop database mysqltest1; use mysqltest1; @@ -29,6 +30,7 @@ while ($1) } --enable_query_log +--replace_result \\ / --error 1010 drop database mysqltest1; use mysqltest1; diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test index 96900697d5b..8076d835ac0 100644 --- a/mysql-test/t/rpl_error_ignored_table.test +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -15,7 +15,7 @@ sync_with_master; # The port number is different when doing the release build with # Do-compile, hence we have to replace the port number here accordingly --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # check that the table has been ignored, because otherwise the test is nonsense show tables like 't1'; diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 21515080ca2..65855dd3ceb 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -72,7 +72,7 @@ set global sql_slave_skip_counter=1; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # Trigger error again to test CHANGE MASTER @@ -92,7 +92,7 @@ stop slave; change master to master_user='test'; change master to master_user='root'; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # Trigger error again to test RESET SLAVE @@ -114,7 +114,7 @@ wait_for_slave_to_stop; stop slave; reset slave; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # Finally, see if logging is done ok on master for a failing LOAD DATA INFILE diff --git a/mysql-test/t/rpl_log-master.opt b/mysql-test/t/rpl_log-master.opt index e0d075c3fbd..cef79bc8585 100644 --- a/mysql-test/t/rpl_log-master.opt +++ b/mysql-test/t/rpl_log-master.opt @@ -1 +1 @@ ---skip-external-locking +--force-restart diff --git a/mysql-test/t/rpl_log.test b/mysql-test/t/rpl_log.test index 08aa3b28850..40fc36cad4a 100644 --- a/mysql-test/t/rpl_log.test +++ b/mysql-test/t/rpl_log.test @@ -94,7 +94,7 @@ show binlog events in 'slave-bin.000001' from 4; --replace_result $MASTER_MYPORT MASTER_PORT $VERSION VERSION show binlog events in 'slave-bin.000002' from 4; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # Need to recode the following diff --git a/mysql-test/t/rpl_max_relay_size.test b/mysql-test/t/rpl_max_relay_size.test index 63d7ef35413..003f60df28f 100644 --- a/mysql-test/t/rpl_max_relay_size.test +++ b/mysql-test/t/rpl_max_relay_size.test @@ -38,7 +38,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # --vertical_results show slave status; @@ -53,7 +53,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # --vertical_results show slave status; @@ -68,7 +68,7 @@ select @@global.max_relay_log_size; start slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # --vertical_results show slave status; @@ -82,7 +82,7 @@ reset slave; # (to make sure it does not crash). flush logs; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # --vertical_results show slave status; @@ -103,7 +103,7 @@ save_master_pos; connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # --vertical_results show slave status; @@ -118,7 +118,7 @@ save_master_pos; connection slave; sync_with_master; --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # --vertical_results show slave status; diff --git a/mysql-test/t/rpl_replicate_do.test b/mysql-test/t/rpl_replicate_do.test index 9bbaa9f0076..b8559af2394 100644 --- a/mysql-test/t/rpl_replicate_do.test +++ b/mysql-test/t/rpl_replicate_do.test @@ -33,7 +33,7 @@ connection slave; sync_with_master; # show slave status, just to see of it prints replicate-do-table --replace_result $MASTER_MYPORT MASTER_PORT ---replace_column 1 # 33 # +--replace_column 1 # 8 # 9 # 23 # 33 # show slave status; # From ca817b49cf00eebfb95e7765714a1a0db8913433 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 11:37:07 +0200 Subject: [PATCH 170/235] Fix for bug#23379 "wrong time value in SHOW PROCESSLIST" The value taken to be shown in SHOW PROCESSLIST is not initialized when THD is created and will be random for unauthenticated connections. To the documentor: Random value, instead of NULL, was shown, in SHOW PROCESSLIST for still non-authenticated connections. sql/sql_class.cc: Initialize time_after_lock. It is used from SHOW PROCESSLIST's code. If not initialized random value is shown for connected but still unauthenticated clients in the column Time. --- sql/sql_class.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bd292814bfa..fc9597cba87 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -181,6 +181,7 @@ THD::THD() // Must be reset to handle error with THD's created for init of mysqld lex->current_select= 0; start_time=(time_t) 0; + time_after_lock=(time_t) 0; current_linfo = 0; slave_thread = 0; variables.pseudo_thread_id= 0; From cd06481d658d77567cbf6223a118e0102b93be51 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 13:34:09 +0200 Subject: [PATCH 171/235] Add command "exit" to mysqltest, it will stop processing any more commands and go directly to result file processing client/mysqltest.c: Add command "exit" to mysqltest mysql-test/r/mysqltest.result: Add command "exit" to mysqltest mysql-test/t/mysqltest.test: Add command "exit" to mysqltest --- client/mysqltest.c | 13 ++++++++++--- mysql-test/r/mysqltest.result | 2 ++ mysql-test/t/mysqltest.test | 14 ++++++++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index efb5f1915f4..5bc132a874f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -264,7 +264,7 @@ enum enum_commands { Q_IF, Q_DISABLE_PARSING, Q_ENABLE_PARSING, Q_REPLACE_REGEX, Q_REMOVE_FILE, Q_FILE_EXIST, - Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, + Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_UNKNOWN, /* Unknown command. */ Q_COMMENT, /* Comments, ignored. */ @@ -345,6 +345,8 @@ const char *command_names[]= "copy_file", "perl", "die", + /* Don't execute any more commands, compare result */ + "exit", 0 }; @@ -5429,7 +5431,7 @@ void mark_progress(struct st_command* command __attribute__((unused)), int main(int argc, char **argv) { struct st_command *command; - my_bool q_send_flag= 0; + my_bool q_send_flag= 0, abort_flag= 0; uint command_executed= 0, last_command_executed= 0; char save_file[FN_REFLEN]; MY_STAT res_info; @@ -5549,7 +5551,7 @@ int main(int argc, char **argv) open_file(opt_include); } - while (!read_command(&command)) + while (!read_command(&command) && !abort_flag) { int current_line_inc = 1, processed = 0; if (command->type == Q_UNKNOWN || command->type == Q_COMMENT_WITH_COMMAND) @@ -5777,8 +5779,13 @@ int main(int argc, char **argv) die("Parsing is already enabled"); break; case Q_DIE: + /* Abort test with error code and error message */ die("%s", command->first_argument); break; + case Q_EXIT: + /* Stop processing any more commands */ + abort_flag= 1; + break; case Q_RESULT: die("result, deprecated command"); diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index ed7267fb71d..a63863977b0 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -518,4 +518,6 @@ hello mysqltest: At line 1: Max delimiter length(16) exceeded hello hello +mysqltest: At line 1: test of die +Some output End of tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index d98375ca746..3c20b38722f 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1548,5 +1548,19 @@ perl; print "hello\n"; EOF +# ---------------------------------------------------------------------------- +# test for die +# ---------------------------------------------------------------------------- + +--error 1 +--exec echo "die test of die;" | $MYSQL_TEST 2>&1 + + +# ---------------------------------------------------------------------------- +# test for exit +# ---------------------------------------------------------------------------- + +--exec echo "echo Some output; exit; echo Not this;" | $MYSQL_TEST 2>&1 + --echo End of tests From 9ee717874265adf3a070db903f0c0465414f3d5b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 20:29:33 +0200 Subject: [PATCH 172/235] Fix problem running rpl_timezone on powermacg5, it was not popular to set TZ to "" so now it's set to a value wich is not our default --- mysql-test/lib/mtr_cases.pl | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 88c51728fb2..7a01c66305b 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -263,9 +263,6 @@ sub collect_one_test_case($$$$$$$) { return; } - # ---------------------------------------------------------------------- - # Skip some tests but include in list, just mark them to skip - # ---------------------------------------------------------------------- my $tinfo= {}; $tinfo->{'name'}= $tname; @@ -273,6 +270,10 @@ sub collect_one_test_case($$$$$$$) { $tinfo->{'component_id'} = $component_id; push(@$cases, $tinfo); + # ---------------------------------------------------------------------- + # Skip some tests but include in list, just mark them to skip + # ---------------------------------------------------------------------- + if ( $::opt_skip_test and defined mtr_match_prefix($tname,$::opt_skip_test) ) { $tinfo->{'skip'}= 1; @@ -356,8 +357,9 @@ sub collect_one_test_case($$$$$$$) { $value= mtr_match_prefix($opt, "--default-time-zone="); if ( defined $value ) { - $tinfo->{'timezone'}= ""; - # Fallthrough, add this option + # Set timezone for this test case to something different + $tinfo->{'timezone'}= "GMT-8"; + # Fallthrough, add the --default-time-zone option } # The --restart option forces a restart even if no special From fc9cf7f45de3360bed94b3d30b7638b7395b8bf9 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 19 Oct 2006 20:33:32 +0200 Subject: [PATCH 173/235] Adapt to running from "binary dist" Add function mtr_exe_maybe_exists to look for binaries that is optional Skip ndb support if it's a binary dist where mysqld supports ndb but there is no ndbd mysql-test/lib/mtr_misc.pl: Add function mtr_exe_maybe_exists mysql-test/mysql-test-run.pl: Adapt to running from binary dist Add function mtr_exe_maybe_exists to look for binaries that is optional Skip ndb support if it's a binary dist where mysqld supports ndb but there is no ndbd --- mysql-test/lib/mtr_misc.pl | 14 +++++++- mysql-test/mysql-test-run.pl | 66 ++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index dd9d24ebc8e..5ac89aee62c 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -14,6 +14,7 @@ sub mtr_path_exists(@); sub mtr_script_exists(@); sub mtr_file_exists(@); sub mtr_exe_exists(@); +sub mtr_exe_maybe_exists(@); sub mtr_copy_dir($$); sub mtr_same_opts($$); sub mtr_cmp_opts($$); @@ -110,8 +111,9 @@ sub mtr_file_exists (@) { return ""; } -sub mtr_exe_exists (@) { +sub mtr_exe_maybe_exists (@) { my @path= @_; + map {$_.= ".exe"} @path if $::glob_win32; foreach my $path ( @path ) { @@ -124,6 +126,16 @@ sub mtr_exe_exists (@) { return $path if -x $path; } } + return ""; +} + +sub mtr_exe_exists (@) { + my @path= @_; + if (my $path= mtr_exe_maybe_exists(@path)) + { + return $path; + } + # Could not find exe, show error if ( @path == 1 ) { mtr_error("Could not find $path[0]"); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index daa5b8aca96..286bb8a11c5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1313,9 +1313,8 @@ sub executable_setup () { } # Look for language files and charsetsdir, use same share - my $path_share= mtr_path_exists("$glob_basedir/share", + my $path_share= mtr_path_exists("$glob_basedir/share/mysql", "$glob_basedir/sql/share", - "$glob_basedir/share/mysql", "$glob_basedir/share"); $path_language= mtr_path_exists("$path_share/english"); @@ -1373,31 +1372,31 @@ sub executable_setup () { { # Look for ndb tols and binaries my $ndb_path= mtr_path_exists("$glob_basedir/ndb", - "$glob_basedir/storage/ndb"); + "$glob_basedir/storage/ndb", + "$glob_basedir/bin"); $path_ndb_tools_dir= mtr_path_exists("$ndb_path/tools", - "$glob_basedir/bin"); + "$ndb_path"); $exe_ndb_mgm= mtr_exe_exists("$ndb_path/src/mgmclient/ndb_mgm", - "$glob_basedir/bin/ndb_mgm"); + "$ndb_path/ndb_mgm"); $exe_ndb_mgmd= mtr_exe_exists("$ndb_path/src/mgmsrv/ndb_mgmd", - "$glob_basedir/bin/ndb_mgmd"); + "$ndb_path/ndb_mgmd"); $exe_ndb_waiter= mtr_exe_exists("$ndb_path/tools/ndb_waiter", - "$glob_basedir/bin/ndb_waiter"); + "$ndb_path/ndb_waiter"); $exe_ndbd= mtr_exe_exists("$ndb_path/src/kernel/ndbd", - "$glob_basedir/bin/ndbd"); + "$ndb_path/ndbd"); - if ( $mysql_version_id >= 50000 ) - { - $path_ndb_examples_dir= - mtr_path_exists("$ndb_path/ndbapi-examples", - "$ndb_path/examples"); - $exe_ndb_example= - mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); - } + # May not exist + $path_ndb_examples_dir= + mtr_file_exists("$ndb_path/ndbapi-examples", + "$ndb_path/examples"); + # May not exist + $exe_ndb_example= + mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); } # Look for the udf_example library @@ -1420,27 +1419,20 @@ sub executable_setup () { } - if ( $glob_win32 and $mysql_version_id < 50000 ) + # Look for mysql_client_test executable which may _not_ exist in + # some versions, test using it should be skipped + if ( $glob_use_embedded_server ) { - # Skip looking for exe_mysql_client_test as its not built by default - # in 4.1 for windows. - $exe_mysql_client_test= "unavailable"; + $exe_mysql_client_test= + mtr_exe_maybe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); } else { - # Look for mysql_client_test executable - if ( $glob_use_embedded_server ) - { - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); - } - else - { - $exe_mysql_client_test= - mtr_exe_exists("$glob_basedir/tests/mysql_client_test", - "$glob_basedir/tests/release/mysql_client_test", - "$glob_basedir/tests/debug/mysql_client_test"); - } + $exe_mysql_client_test= + mtr_exe_maybe_exists("$glob_basedir/tests/mysql_client_test", + "$glob_basedir/tests/release/mysql_client_test", + "$glob_basedir/tests/debug/mysql_client_test", + "$glob_basedir/bin"); } } @@ -2045,6 +2037,14 @@ sub check_ndbcluster_support ($) { $opt_skip_ndbcluster_slave= 1; return; } + elsif ( -e "$glob_basedir/bin" && ! -f "$glob_basedir/bin/ndbd") + { + # Binary dist with a mysqld that supports ndb, but no ndbd found + mtr_report("Skipping ndbcluster, can't fint binaries"); + $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster_slave= 1; + return; + } $glob_ndbcluster_supported= 1; mtr_report("Using ndbcluster when necessary, mysqld supports it"); From 4ba691b03c90c3d3af5445ef177fbbbd63efa8e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 15:08:25 +0500 Subject: [PATCH 174/235] Fix for bug #22723: Host field blank when server started with skip-grant We set 'host_or_ip' to "" in the Security_context::skip_grants(). sql/sql_show.cc: Fix for bug #22723: Host field blank when server started with skip-grant - as we set 'host_or_ip' to "" if skip-grant, use 'host' instead. --- sql/sql_show.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eb78f4fbdae..2240601a661 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1323,7 +1323,9 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port); } else - thd_info->host= thd->strdup(tmp_sctx->host_or_ip); + thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ? + tmp_sctx->host_or_ip : + tmp_sctx->host ? tmp_sctx->host : ""); if ((thd_info->db=tmp->db)) // Safe test thd_info->db=thd->strdup(thd_info->db); thd_info->command=(int) tmp->command; From dd18eb1bfc8dc9839dda8b2e0ff3df0555a079b2 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 14:31:47 +0400 Subject: [PATCH 175/235] Fix for bug #23256 "doesn't build on alpha" - compilation on the Alpha platform was broken because the Alpha-specific code was not updated after replacing the SIGRETURN_FRAME_COUNT constant with a variable --- sql/stacktrace.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/stacktrace.c b/sql/stacktrace.c index 43f35c452f7..1b8267763a0 100644 --- a/sql/stacktrace.c +++ b/sql/stacktrace.c @@ -186,7 +186,7 @@ terribly wrong...\n"); #if defined(__alpha__) && defined(__GNUC__) uchar** new_fp = find_prev_fp(pc, fp); - if (frame_count == SIGRETURN_FRAME_COUNT - 1) + if (frame_count == sigreturn_frame_count - 1) { new_fp += 90; } From 12c43f4f15e505c0db34c46dbcd90f27a7334345 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 17:09:07 +0200 Subject: [PATCH 176/235] Init some variables that changes between test cases direclty in run_testcase This can not be done in run_testcase_start_servers as embedded never starts a server Add error if mysqld_start is called in embedded mode --- mysql-test/mysql-test-run.pl | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 286bb8a11c5..7dac63b5373 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2880,6 +2880,13 @@ sub find_testcase_skipped_reason($) sub run_testcase ($) { my $tinfo= shift; + # ------------------------------------------------------- + # Init variables that can change between each test case + # ------------------------------------------------------- + + $ENV{'TZ'}= $tinfo->{'timezone'}; + mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}"); + my $master_restart= run_testcase_need_master_restart($tinfo); my $slave_restart= run_testcase_need_slave_restart($tinfo); @@ -3409,6 +3416,9 @@ sub mysqld_start ($$$) { my $type= $mysqld->{'type'}; my $idx= $mysqld->{'idx'}; + mtr_error("Internal error: mysqld should never be started for embedded") + if $glob_use_embedded_server; + if ( $type eq 'master' ) { $exe= $exe_master_mysqld; @@ -3849,12 +3859,6 @@ sub run_testcase_start_servers($) { my $tinfo= shift; my $tname= $tinfo->{'name'}; - # ------------------------------------------------------- - # Init variables that can change between server starts - # ------------------------------------------------------- - $ENV{'TZ'}= $tinfo->{'timezone'}; - mtr_verbose("Starting server with timezone: $tinfo->{'timezone'}"); - if ( $tinfo->{'component_id'} eq 'mysqld' ) { if ( ! $opt_skip_ndbcluster and From 7c7ea371cd6190307f7c7f1a8e59729feefb864b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 12:34:31 -0600 Subject: [PATCH 177/235] Apply InnoDB snapshot ss923 Fixes: - Bug #18077: InnoDB uses full explicit table locks in stored FUNCTION sql/ha_innodb.cc: Apply InnoDB snapshot ss923 Revision r922: ha_innobase::store_lock(): When downgrading table locks, do not check thd->in_lock_tables but test if thd->lex->sql_command == SQLCOM_LOCK_TABLES instead. Otherwise, stored functions will use table locks. (Bug #18077) --- sql/ha_innodb.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index e99d93784c9..e018ad8a3b4 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -6563,7 +6563,8 @@ ha_innobase::store_lock( && lock_type != TL_IGNORE)) { /* The OR cases above are in this order: - 1) MySQL is doing LOCK TABLES ... READ LOCAL, or + 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we + are processing a stored procedure or function, or 2) (we do not know when TL_READ_HIGH_PRIORITY is used), or 3) this is a SELECT ... IN SHARE MODE, or 4) we are doing a complex SQL statement like @@ -6625,7 +6626,8 @@ ha_innobase::store_lock( single transaction stored procedure call deterministic (if it does not use a consistent read). */ - if (lock_type == TL_READ && thd->in_lock_tables) { + if (lock_type == TL_READ + && thd->lex->sql_command == SQLCOM_LOCK_TABLES) { /* We come here if MySQL is processing LOCK TABLES ... READ LOCAL. MyISAM under that table lock type reads the table as it was at the time the lock was @@ -6684,8 +6686,7 @@ ha_innobase::store_lock( (MySQL does have thd->in_lock_tables TRUE there). */ if (lock_type == TL_READ_NO_INSERT - && (!thd->in_lock_tables - || thd->lex->sql_command == SQLCOM_CALL)) { + && thd->lex->sql_command != SQLCOM_LOCK_TABLES) { lock_type = TL_READ; } From f6f91b9d3b5290c1f48f518cb9e7cdbe3652ee1b Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 12:36:15 -0600 Subject: [PATCH 178/235] Apply InnoDB snapshot ss923 Fixes: - Bug #18077: InnoDB uses full explicit table locks in stored FUNCTION storage/innobase/btr/btr0btr.c: Apply InnoDB snapshot ss923 Revision r919: btr_page_get_father_for_rec(): Remove bogus comment about removed dict_tree_t. storage/innobase/dict/dict0dict.c: Apply InnoDB snapshot ss923 Revision r892: Merge changes from MySQL AB. dict_col_copy_type_noninline(): Remove the return statement. Some compilers do not allow return expressions of void type. innobase_start_or_create_for_mysql(): Do not cap srv_max_threads to 1000 on Windows. Makefile.am (EXTRA_DIST): Add plug.in Revision r897: dict_index_get_if_in_cache(): Enclose in #ifdef UNIV_DEBUG. Replace the search loop with a call to dict_index_find_on_id_low(). storage/innobase/handler/ha_innodb.cc: Apply InnoDB snapshot ss923 Revision r887: storage/innobase/handler: Merge changes from MySQL AB: ChangeSet 2006/09/30 18:44:42-07:00 brian@zim.(none) Merge zim.(none):/home/brian/mysql/merge-5.1 into zim.(none):/home/brian/mysql/arch-5.1 ChangeSet 2006/09/30 12:49:46-07:00 brian@zim.(none) This patch adds handlerton passing to functions. NDB and Innodb still require a global hanlderton in the main code due to the nature of the sql_cache call back function (should be solveable... another patch). Partitioning now has a flag to allow disabling of engines from being compatible with partitioning. Cleaned up heap naming convention on panic call. ChangeSet 2006/09/29 17:19:02-07:00 brian@zim.(none) This removes the passing of global hton to engine instance. ChangeSet 2006/09/28 13:22:56+02:00 gbichot@dl145h.mysql.com Merge gbichot@bk-internal:/home/bk/mysql-5.1-arch into dl145h.mysql.com:/users/gbichot/mysql-5.1-arch ChangeSet 2006/09/28 13:19:43+02:00 gbichot@dl145h.mysql.com In the handlerton, cursor creation function don't have an argument and so the engine calls current_thd to derive transaction information; instead we now pass THD to those functions, it looks more logical (it makes the implicit current_thd parameter more visible). Approved by Brian and Monty. ChangeSet 2006/09/26 22:51:53-07:00 brian@zim.(none) Merge zim.(none):/home/brian/mysql/merge-5.1 into zim.(none):/home/brian/mysql/arch-5.1 Revision r895: Merge changes from MySQL AB, and remove two compilation warnings. ha_innodb.cc: innodb_mutex_show_status(): Add (ulong) casts to ulonglong expressions being passed to fprintf %lu. The warnings were apparently introduced by MySQL AB developers. mysql_declare_plugin(innobase): Add PLUGIN_LICENSE_GPL. have_innodb.inc: Merge changes from MySQL AB. Revision r923: ha_innobase::store_lock(): When downgrading table locks, do not check thd->in_lock_tables but test if thd->lex->sql_command == SQLCOM_LOCK_TABLES instead. Otherwise, stored functions will use table locks. (Bug #18077) This patch is from Heikki. storage/innobase/include/dict0dict.h: Apply InnoDB snapshot ss923 Revision r897: dict_index_get_if_in_cache(): Enclose in #ifdef UNIV_DEBUG. Replace the search loop with a call to dict_index_find_on_id_low(). storage/innobase/include/mem0dbg.h: Apply InnoDB snapshot ss923 Revision r901: Enclose some mem debug functions in #ifdef UNIV_DEBUG or #ifdef UNIV_MEM_DEBUG. storage/innobase/include/mtr0mtr.h: Apply InnoDB snapshot ss923 Revision r866: mtr_print(), mtr_memo_contains(): Disable unless #ifdef UNIV_DEBUG. storage/innobase/include/mtr0mtr.ic: Apply InnoDB snapshot ss923 Revision r866: mtr_print(), mtr_memo_contains(): Disable unless #ifdef UNIV_DEBUG. storage/innobase/include/sync0rw.h: Apply InnoDB snapshot ss923 Revision r907: Send all SHOW ENGINE INNODB STATUS information to the client also when UNIV_SYNC_DEBUG is defined. rw_lock_list_print_info(): Add parameter "file". mutex_list_print_info(): Add parameter "file". Make the function static. storage/innobase/include/sync0sync.h: Apply InnoDB snapshot ss923 Revision r907: Send all SHOW ENGINE INNODB STATUS information to the client also when UNIV_SYNC_DEBUG is defined. rw_lock_list_print_info(): Add parameter "file". mutex_list_print_info(): Add parameter "file". Make the function static. storage/innobase/include/univ.i: Apply InnoDB snapshot ss923 Revision r894: univ.i: Indent some of the directives, and remove conditions about Windows in the "#else" branch of "#if building on Windows". storage/innobase/mem/mem0dbg.c: Apply InnoDB snapshot ss923 Revision r901: Enclose some mem debug functions in #ifdef UNIV_DEBUG or #ifdef UNIV_MEM_DEBUG. Revision r902: mem0dbg.c: Enclose some more function definitions in #ifdef UNIV_MEM_DEBUG. The declarations were already enclosed in #ifdef UNIV_MEM_DEBUG. storage/innobase/mem/mem0pool.c: Apply InnoDB snapshot ss923 Revision r896: mem0pool.c: Remove obsolete comments about the dictionary cache being managed with an LRU algorithm. storage/innobase/mtr/mtr0mtr.c: Apply InnoDB snapshot ss923 Revision r866: mtr_print(), mtr_memo_contains(): Disable unless #ifdef UNIV_DEBUG. storage/innobase/row/row0purge.c: Apply InnoDB snapshot ss923 Revision r869: row_purge_parse_undo_rec(): Correct a faulty condition. Luckily, this bug would only surface if the InnoDB SQL interpreter were used for updating fixed-length columns. Currently (as the UPD_NODE_NO_SIZE_CHANGE flag is never set), cmpl_info can only be 0 or UPD_NODE_NO_ORD_CHANGE. Luckily, UPD_NODE_NO_ORD_CHANGE is 1, and the condition was simplified to !cmpl_info. storage/innobase/sync/sync0rw.c: Apply InnoDB snapshot ss923 Revision r907: Send all SHOW ENGINE INNODB STATUS information to the client also when UNIV_SYNC_DEBUG is defined. rw_lock_list_print_info(): Add parameter "file". mutex_list_print_info(): Add parameter "file". Make the function static. storage/innobase/sync/sync0sync.c: Apply InnoDB snapshot ss923 Revision r907: Send all SHOW ENGINE INNODB STATUS information to the client also when UNIV_SYNC_DEBUG is defined. rw_lock_list_print_info(): Add parameter "file". mutex_list_print_info(): Add parameter "file". Make the function static. --- storage/innobase/btr/btr0btr.c | 3 -- storage/innobase/dict/dict0dict.c | 22 ++-------- storage/innobase/handler/ha_innodb.cc | 13 +++--- storage/innobase/include/dict0dict.h | 4 +- storage/innobase/include/mem0dbg.h | 13 ++---- storage/innobase/include/mtr0mtr.h | 2 + storage/innobase/include/mtr0mtr.ic | 2 + storage/innobase/include/sync0rw.h | 5 ++- storage/innobase/include/sync0sync.h | 6 --- storage/innobase/include/univ.i | 59 ++++++++++++--------------- storage/innobase/mem/mem0dbg.c | 14 +++---- storage/innobase/mem/mem0pool.c | 17 ++++---- storage/innobase/mtr/mtr0mtr.c | 2 + storage/innobase/row/row0purge.c | 2 +- storage/innobase/sync/sync0rw.c | 15 +++---- storage/innobase/sync/sync0sync.c | 19 +++++---- 16 files changed, 83 insertions(+), 115 deletions(-) diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index ffaf2065045..7a8e5626e25 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -571,9 +571,6 @@ btr_page_get_father_for_rec( tuple = dict_index_build_node_ptr(index, user_rec, 0, heap, btr_page_get_level(page, mtr)); - /* In the following, we choose just any index from the tree as the - first parameter for btr_cur_search_to_nth_level. */ - btr_cur_search_to_nth_level(index, btr_page_get_level(page, mtr) + 1, tuple, PAGE_CUR_LE, diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 44a374fe550..d74d5036b1a 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -3547,6 +3547,7 @@ syntax_error: /*==================== END OF FOREIGN KEY PROCESSING ====================*/ +#ifdef UNIV_DEBUG /************************************************************************** Returns an index object if it is found in the dictionary cache. */ @@ -3556,7 +3557,6 @@ dict_index_get_if_in_cache( /* out: index, NULL if not found */ dulint index_id) /* in: index id */ { - dict_table_t* table; dict_index_t* index; if (dict_sys == NULL) { @@ -3565,29 +3565,13 @@ dict_index_get_if_in_cache( mutex_enter(&(dict_sys->mutex)); - table = UT_LIST_GET_FIRST(dict_sys->table_LRU); + index = dict_index_find_on_id_low(index_id); - while (table) { - index = UT_LIST_GET_FIRST(table->indexes); - - while (index) { - if (0 == ut_dulint_cmp(index->id, index_id)) { - - goto found; - } - - index = UT_LIST_GET_NEXT(indexes, index); - } - - table = UT_LIST_GET_NEXT(table_LRU, table); - } - - index = NULL; -found: mutex_exit(&(dict_sys->mutex)); return(index); } +#endif /* UNIV_DEBUG */ #ifdef UNIV_DEBUG /************************************************************************** diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 066c0ce48d4..0e4e6251dbc 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6630,7 +6630,7 @@ innodb_mutex_show_status( mutex->count_spin_rounds, mutex->count_os_wait, mutex->count_os_yield, - mutex->lspent_time/1000); + (ulong) mutex->lspent_time/1000); if (stat_print(thd, innobase_hton_name, hton_name_len, buf1, buf1len, @@ -6660,7 +6660,7 @@ innodb_mutex_show_status( rw_lock_count, rw_lock_count_spin_loop, rw_lock_count_spin_rounds, rw_lock_count_os_wait, rw_lock_count_os_yield, - rw_lock_wait_time/1000); + (ulong) rw_lock_wait_time/1000); if (stat_print(thd, innobase_hton_name, hton_name_len, STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) { @@ -6812,7 +6812,8 @@ ha_innobase::store_lock( && lock_type != TL_IGNORE)) { /* The OR cases above are in this order: - 1) MySQL is doing LOCK TABLES ... READ LOCAL, or + 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we + are processing a stored procedure or function, or 2) (we do not know when TL_READ_HIGH_PRIORITY is used), or 3) this is a SELECT ... IN SHARE MODE, or 4) we are doing a complex SQL statement like @@ -6880,7 +6881,8 @@ ha_innobase::store_lock( single transaction stored procedure call deterministic (if it does not use a consistent read). */ - if (lock_type == TL_READ && thd->in_lock_tables) { + if (lock_type == TL_READ + && thd->lex->sql_command == SQLCOM_LOCK_TABLES) { /* We come here if MySQL is processing LOCK TABLES ... READ LOCAL. MyISAM under that table lock type reads the table as it was at the time the lock was @@ -6939,8 +6941,7 @@ ha_innobase::store_lock( (MySQL does have thd->in_lock_tables TRUE there). */ if (lock_type == TL_READ_NO_INSERT - && (!thd->in_lock_tables - || thd->lex->sql_command == SQLCOM_CALL)) { + && thd->lex->sql_command != SQLCOM_LOCK_TABLES) { lock_type = TL_READ; } diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index a9775ab3d40..2582effbb29 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -778,9 +778,8 @@ const dict_col_t* dict_field_get_col( /*===============*/ const dict_field_t* field); -/************************************************************************** -In an index tree, finds the index corresponding to a record in the tree. */ +#ifdef UNIV_DEBUG /************************************************************************** Returns an index object if it is found in the dictionary cache. */ @@ -789,7 +788,6 @@ dict_index_get_if_in_cache( /*=======================*/ /* out: index, NULL if not found */ dulint index_id); /* in: index id */ -#ifdef UNIV_DEBUG /************************************************************************** Checks that a tuple has n_fields_cmp value in a sensible range, so that no comparison can occur with the page number field in a node pointer. */ diff --git a/storage/innobase/include/mem0dbg.h b/storage/innobase/include/mem0dbg.h index 0f4441f4f9d..36cd7a89565 100644 --- a/storage/innobase/include/mem0dbg.h +++ b/storage/innobase/include/mem0dbg.h @@ -30,6 +30,7 @@ check fields at the both ends of the field. */ #define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #endif +#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG /******************************************************************* Checks a memory heap for consistency and prints the contents if requested. Outputs the sum of sizes of buffers given to the user (only in @@ -59,15 +60,8 @@ mem_heap_validate_or_print( ulint* n_blocks); /* out: number of blocks in the heap, if a NULL pointer is passed as this argument, it is ignored */ -#ifdef UNIV_MEM_DEBUG -/****************************************************************** -Prints the contents of a memory heap. */ - -void -mem_heap_print( -/*===========*/ - mem_heap_t* heap); /* in: memory heap */ -#endif /* UNIV_MEM_DEBUG */ +#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */ +#ifdef UNIV_DEBUG /****************************************************************** Checks that an object is a memory heap (or a block of it) */ @@ -76,6 +70,7 @@ mem_heap_check( /*===========*/ /* out: TRUE if ok */ mem_heap_t* heap); /* in: memory heap */ +#endif /* UNIV_DEBUG */ /****************************************************************** Validates the contents of a memory heap. */ diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 9e8250cb545..2a160d27e0c 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -265,6 +265,7 @@ mtr_memo_release( mtr_t* mtr, /* in: mtr */ void* object, /* in: object */ ulint type); /* in: object type: MTR_MEMO_S_LOCK, ... */ +#ifdef UNIV_DEBUG /************************************************************** Checks if memo contains the given item. */ UNIV_INLINE @@ -282,6 +283,7 @@ void mtr_print( /*======*/ mtr_t* mtr); /* in: mtr */ +#endif /* UNIV_DEBUG */ /*######################################################################*/ #define MTR_BUF_MEMO_SIZE 200 /* number of slots in memo */ diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic index d81f6cb9c0d..81eec3bfc92 100644 --- a/storage/innobase/include/mtr0mtr.ic +++ b/storage/innobase/include/mtr0mtr.ic @@ -113,6 +113,7 @@ mtr_release_s_latch_at_savepoint( slot->object = NULL; } +#ifdef UNIV_DEBUG /************************************************************** Checks if memo contains the given item. */ UNIV_INLINE @@ -148,6 +149,7 @@ mtr_memo_contains( return(FALSE); } +#endif /* UNIV_DEBUG */ /******************************************************************* Returns the log object of a mini-transaction buffer. */ diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index d8f3c400918..7c0241f2e02 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -358,8 +358,9 @@ rw_lock_print( Prints debug info of currently locked rw-locks. */ void -rw_lock_list_print_info(void); -/*=========================*/ +rw_lock_list_print_info( +/*====================*/ + FILE* file); /* in: file where to print */ /******************************************************************* Returns the number of currently locked rw-locks. Works only in the debug version. */ diff --git a/storage/innobase/include/sync0sync.h b/storage/innobase/include/sync0sync.h index 7d795e60efd..a1184d44257 100644 --- a/storage/innobase/include/sync0sync.h +++ b/storage/innobase/include/sync0sync.h @@ -224,12 +224,6 @@ Counts currently reserved mutexes. Works only in the debug version. */ ulint mutex_n_reserved(void); /*==================*/ -/********************************************************************** -Prints debug info of currently reserved mutexes. */ - -void -mutex_list_print_info(void); -/*========================*/ #endif /* UNIV_SYNC_DEBUG */ /********************************************************************** NOT to be used outside this module except in debugging! Gets the value diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 63fdabbe823..8765987d472 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -10,18 +10,18 @@ Created 1/20/1994 Heikki Tuuri #define univ_i #if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__) -#undef __WIN__ -#define __WIN__ +# undef __WIN__ +# define __WIN__ -#include +# include -#if !defined(WIN64) && !defined(_WIN64) -#define UNIV_CAN_USE_X86_ASSEMBLER -#endif +# if !defined(WIN64) && !defined(_WIN64) +# define UNIV_CAN_USE_X86_ASSEMBLER +# endif -#ifdef _NT_ -#define __NT__ -#endif +# ifdef _NT_ +# define __NT__ +# endif #else /* The defines used with MySQL */ @@ -30,42 +30,33 @@ Created 1/20/1994 Heikki Tuuri in compiling more Posix-compatible. These headers also define __WIN__ if we are compiling on Windows. */ -#include -#include +# include +# include /* Include to get S_I... macros defined for os0file.c */ -#include +# include -#undef PACKAGE -#undef VERSION +# undef PACKAGE +# undef VERSION /* Include the header file generated by GNU autoconf */ -#ifndef __WIN__ -#include "config.h" -#endif +# include "config.h" -#ifdef HAVE_SCHED_H -#include -#endif - -/* When compiling for Itanium IA64, undefine the flag below to prevent use -of the 32-bit x86 assembler in mutex operations. */ - -#if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) -#define UNIV_CAN_USE_X86_ASSEMBLER -#endif +# ifdef HAVE_SCHED_H +# include +# endif /* We only try to do explicit inlining of functions with gcc and Microsoft Visual C++ */ -#if !defined(__GNUC__) && !defined(__WIN__) -#undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */ -#define UNIV_MUST_NOT_INLINE -#endif +# if !defined(__GNUC__) +# undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */ +# define UNIV_MUST_NOT_INLINE +# endif -#ifdef HAVE_PREAD -#define HAVE_PWRITE -#endif +# ifdef HAVE_PREAD +# define HAVE_PWRITE +# endif #endif /* #if (defined(WIN32) || ... */ diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c index 419f410cf1b..eb77dd01f6d 100644 --- a/storage/innobase/mem/mem0dbg.c +++ b/storage/innobase/mem/mem0dbg.c @@ -66,7 +66,6 @@ mem_hash_get_nth_cell(ulint i) return(&(mem_hash_table[i])); } -#endif /* UNIV_MEM_DEBUG */ /* Accessor functions for a memory field in the debug version */ @@ -106,6 +105,7 @@ mem_field_trailer_get_check(byte* field) return(mach_read_from_4(field + mem_field_header_get_len(field))); } +#endif /* UNIV_MEM_DEBUG */ /********************************************************************** Initializes the memory system. */ @@ -136,6 +136,7 @@ mem_init( mem_comm_pool = mem_pool_create(size); } +#ifdef UNIV_MEM_DEBUG /********************************************************************** Initializes an allocated memory field in the debug version. */ @@ -163,7 +164,6 @@ mem_field_init( mem_field_header_set_check(usr_buf, rnd); mem_field_trailer_set_check(usr_buf, rnd); -#ifdef UNIV_MEM_DEBUG /* Update the memory allocation information */ mutex_enter(&mem_hash_mutex); @@ -182,7 +182,6 @@ mem_field_init( combination of 0xBA and 0xBE */ mem_init_buf(usr_buf, n); -#endif /* UNIV_MEM_DEBUG */ } /********************************************************************** @@ -199,7 +198,6 @@ mem_field_erase( usr_buf = buf + MEM_FIELD_HEADER_SIZE; -#ifdef UNIV_MEM_DEBUG mutex_enter(&mem_hash_mutex); mem_current_allocated_memory -= n; mutex_exit(&mem_hash_mutex); @@ -211,10 +209,8 @@ mem_field_erase( combination of 0xDE and 0xAD */ mem_erase_buf(buf, MEM_SPACE_NEEDED(n)); -#endif /* UNIV_MEM_DEBUG */ } -#ifdef UNIV_MEM_DEBUG /******************************************************************* Initializes a buffer to a random combination of hex BA and BE. Used to initialize allocated memory. */ @@ -376,6 +372,7 @@ mem_hash_remove( } #endif /* UNIV_MEM_DEBUG */ +#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG /******************************************************************* Checks a memory heap for consistency and prints the contents if requested. Outputs the sum of sizes of buffers given to the user (only in @@ -549,10 +546,12 @@ completed: } *error = FALSE; } +#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */ +#ifdef UNIV_DEBUG /****************************************************************** Prints the contents of a memory heap. */ - +static void mem_heap_print( /*===========*/ @@ -615,6 +614,7 @@ mem_heap_validate( return(TRUE); } +#endif /* UNIV_DEBUG */ #ifdef UNIV_MEM_DEBUG /********************************************************************* diff --git a/storage/innobase/mem/mem0pool.c b/storage/innobase/mem/mem0pool.c index 6a419ff33ec..a7acd331e16 100644 --- a/storage/innobase/mem/mem0pool.c +++ b/storage/innobase/mem/mem0pool.c @@ -35,7 +35,7 @@ The main components of the memory consumption are: 8. session for each user, and 9. stack for each OS thread. -Items 1-3 are managed by an LRU algorithm. Items 5 and 6 can potentially +Items 1 and 2 are managed by an LRU algorithm. Items 5 and 6 can potentially consume very much memory. Items 7 and 8 should consume quite little memory, and the OS should take care of item 9, which too should consume little memory. @@ -54,16 +54,15 @@ common pool and the buffers in the buffer pool into a single LRU list and manage it uniformly, but this approach does not take into account the parsing and other costs unique to SQL statements. -So, let the SQL statements and the data dictionary entries form one single -LRU list, let us call it the dictionary LRU list. The locks for a transaction -can be seen as a part of the state of the transaction. Hence, they should be -stored in the common pool. We still have the problem of a very big update -transaction, for example, which will set very many x-locks on rows, and the -locks will consume a lot of memory, say, half of the buffer pool size. +The locks for a transaction can be seen as a part of the state of the +transaction. Hence, they should be stored in the common pool. We still +have the problem of a very big update transaction, for example, which +will set very many x-locks on rows, and the locks will consume a lot +of memory, say, half of the buffer pool size. Another problem is what to do if we are not able to malloc a requested -block of memory from the common pool. Then we can truncate the LRU list of -the dictionary cache. If it does not help, a system error results. +block of memory from the common pool. Then we can request memory from +the operating system. If it does not help, a system error results. Because 5 and 6 may potentially consume very much memory, we let them grow into the buffer pool. We may let the locks of a transaction take frames diff --git a/storage/innobase/mtr/mtr0mtr.c b/storage/innobase/mtr/mtr0mtr.c index 1a65da6e7f4..365fa15878a 100644 --- a/storage/innobase/mtr/mtr0mtr.c +++ b/storage/innobase/mtr/mtr0mtr.c @@ -318,6 +318,7 @@ mtr_read_dulint( return(mach_read_from_8(ptr)); } +#ifdef UNIV_DEBUG /************************************************************* Prints info of an mtr handle. */ @@ -332,3 +333,4 @@ mtr_print( (ulong) dyn_array_get_data_size(&(mtr->memo)), (ulong) dyn_array_get_data_size(&(mtr->log))); } +#endif /* UNIV_DEBUG */ diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c index 889a11a7a76..1fef47da13f 100644 --- a/storage/innobase/row/row0purge.c +++ b/storage/innobase/row/row0purge.c @@ -563,7 +563,7 @@ row_purge_parse_undo_rec( /* Read to the partial row the fields that occur in indexes */ - if (!cmpl_info & UPD_NODE_NO_ORD_CHANGE) { + if (!(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) { ptr = trx_undo_rec_get_partial_row(ptr, clust_index, &(node->row), node->heap); } diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c index 304801d0a3b..441933843d7 100644 --- a/storage/innobase/sync/sync0rw.c +++ b/storage/innobase/sync/sync0rw.c @@ -758,8 +758,9 @@ rw_lock_is_locked( Prints debug info of currently locked rw-locks. */ void -rw_lock_list_print_info(void) -/*=========================*/ +rw_lock_list_print_info( +/*====================*/ + FILE* file) /* in: file where to print */ { rw_lock_t* lock; ulint count = 0; @@ -769,7 +770,7 @@ rw_lock_list_print_info(void) fputs("-------------\n" "RW-LATCH INFO\n" - "-------------\n", stderr); + "-------------\n", file); lock = UT_LIST_GET_FIRST(rw_lock_list); @@ -783,12 +784,12 @@ rw_lock_list_print_info(void) || (rw_lock_get_reader_count(lock) != 0) || (rw_lock_get_waiters(lock) != 0)) { - fprintf(stderr, "RW-LOCK: %p ", (void*) lock); + fprintf(file, "RW-LOCK: %p ", (void*) lock); if (rw_lock_get_waiters(lock)) { - fputs(" Waiters for the lock exist\n", stderr); + fputs(" Waiters for the lock exist\n", file); } else { - putc('\n', stderr); + putc('\n', file); } info = UT_LIST_GET_FIRST(lock->debug_list); @@ -802,7 +803,7 @@ rw_lock_list_print_info(void) lock = UT_LIST_GET_NEXT(list, lock); } - fprintf(stderr, "Total number of rw-locks %ld\n", count); + fprintf(file, "Total number of rw-locks %ld\n", count); mutex_exit(&rw_lock_list_mutex); } diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c index 91fd248502a..ff7056b0afe 100644 --- a/storage/innobase/sync/sync0sync.c +++ b/storage/innobase/sync/sync0sync.c @@ -628,10 +628,11 @@ mutex_own( /********************************************************************** Prints debug info of currently reserved mutexes. */ - +static void -mutex_list_print_info(void) -/*=======================*/ +mutex_list_print_info( +/*==================*/ + FILE* file) /* in: file where to print */ { mutex_t* mutex; const char* file_name; @@ -641,7 +642,7 @@ mutex_list_print_info(void) fputs("----------\n" "MUTEX INFO\n" - "----------\n", stderr); + "----------\n", file); mutex_enter(&mutex_list_mutex); @@ -653,7 +654,7 @@ mutex_list_print_info(void) if (mutex_get_lock_word(mutex) != 0) { mutex_get_debug_info(mutex, &file_name, &line, &thread_id); - fprintf(stderr, + fprintf(file, "Locked mutex: addr %p thread %ld" " file %s line %ld\n", (void*) mutex, os_thread_pf(thread_id), @@ -663,7 +664,7 @@ mutex_list_print_info(void) mutex = UT_LIST_GET_NEXT(list, mutex); } - fprintf(stderr, "Total number of mutexes %ld\n", count); + fprintf(file, "Total number of mutexes %ld\n", count); mutex_exit(&mutex_list_mutex); } @@ -1343,7 +1344,7 @@ sync_print_wait_info( FILE* file) /* in: file where to print */ { #ifdef UNIV_SYNC_DEBUG - fprintf(stderr, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n", + fprintf(file, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n", mutex_exit_count, rw_s_exit_count, rw_x_exit_count); #endif @@ -1369,9 +1370,9 @@ sync_print( FILE* file) /* in: file where to print */ { #ifdef UNIV_SYNC_DEBUG - mutex_list_print_info(); + mutex_list_print_info(file); - rw_lock_list_print_info(); + rw_lock_list_print_info(file); #endif /* UNIV_SYNC_DEBUG */ sync_array_print_info(file, sync_primary_wait_array); From ff66bc05f741ec1d3041413f8dba14b4f7891501 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 13:44:49 -0600 Subject: [PATCH 179/235] Applied InnoDB snapshot 5.1-ss927 Fixes: - Bug #23368: crash during insert, table has foreign key pointing into other schema,permission storage/innobase/dict/dict0dict.c: Applied InnoDB snapshot 5.1-ss927 Revision r927: dict_print_info_on_foreign_key_in_create_format(): Use ut_print_name() instead of passing the wrong length to ut_print_namel(). (Bug #23368) ut_print_name(), ut_print_namel(): Document the special treatment of '/'. ut_print_namel(): Replace strchr() with memchr(), as the string might not be NUL-terminated. storage/innobase/include/ut0ut.h: Applied InnoDB snapshot 5.1-ss927 Revision r927: dict_print_info_on_foreign_key_in_create_format(): Use ut_print_name() instead of passing the wrong length to ut_print_namel(). (Bug #23368) ut_print_name(), ut_print_namel(): Document the special treatment of '/'. ut_print_namel(): Replace strchr() with memchr(), as the string might not be NUL-terminated. storage/innobase/ut/ut0ut.c: Applied InnoDB snapshot 5.1-ss927 Revision r927: dict_print_info_on_foreign_key_in_create_format(): Use ut_print_name() instead of passing the wrong length to ut_print_namel(). (Bug #23368) ut_print_name(), ut_print_namel(): Document the special treatment of '/'. ut_print_namel(): Replace strchr() with memchr(), as the string might not be NUL-terminated. --- storage/innobase/dict/dict0dict.c | 12 +----------- storage/innobase/include/ut0ut.h | 10 ++++++++-- storage/innobase/ut/ut0ut.c | 12 +++++++++--- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index d74d5036b1a..7c2fc18accd 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -4146,18 +4146,8 @@ dict_print_info_on_foreign_key_in_create_format( dict_remove_db_name( foreign->referenced_table_name)); } else { - /* Look for the '/' in the table name */ - - i = 0; - while (foreign->referenced_table_name[i] != '/') { - i++; - } - - ut_print_namel(file, trx, TRUE, - foreign->referenced_table_name, i); - putc('.', file); ut_print_name(file, trx, TRUE, - foreign->referenced_table_name + i + 1); + foreign->referenced_table_name); } putc(' ', file); diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h index 1eafa680d8d..b4e9fa91491 100644 --- a/storage/innobase/include/ut0ut.h +++ b/storage/innobase/include/ut0ut.h @@ -218,7 +218,10 @@ ut_print_filename( struct trx_struct; /************************************************************************** -Outputs a NUL-terminated string, quoted as an SQL identifier. */ +Outputs a fixed-length string, quoted as an SQL identifier. +If the string contains a slash '/', the string will be +output as two identifiers separated by a period (.), +as in SQL database_name.identifier. */ void ut_print_name( @@ -230,7 +233,10 @@ ut_print_name( const char* name); /* in: name to print */ /************************************************************************** -Outputs a fixed-length string, quoted as an SQL identifier. */ +Outputs a fixed-length string, quoted as an SQL identifier. +If the string contains a slash '/', the string will be +output as two identifiers separated by a period (.), +as in SQL database_name.identifier. */ void ut_print_namel( diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index 10641b88a17..d805cc3b4b2 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -394,7 +394,10 @@ done: } /************************************************************************** -Outputs a NUL-terminated string, quoted as an SQL identifier. */ +Outputs a fixed-length string, quoted as an SQL identifier. +If the string contains a slash '/', the string will be +output as two identifiers separated by a period (.), +as in SQL database_name.identifier. */ void ut_print_name( @@ -409,7 +412,10 @@ ut_print_name( } /************************************************************************** -Outputs a fixed-length string, quoted as an SQL identifier. */ +Outputs a fixed-length string, quoted as an SQL identifier. +If the string contains a slash '/', the string will be +output as two identifiers separated by a period (.), +as in SQL database_name.identifier. */ void ut_print_namel( @@ -424,7 +430,7 @@ ut_print_namel( #ifdef UNIV_HOTBACKUP fwrite(name, 1, namelen, f); #else - char* slash = strchr(name, '/'); + char* slash = memchr(name, '/', namelen); if (UNIV_LIKELY_NULL(slash)) { /* Print the database name and table name separately. */ From f565eaf21fdd8c567cd41292553e8b2f74bdc2b9 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 17:44:03 -0400 Subject: [PATCH 180/235] Fix bad merge from #14262. sql/sql_trigger.cc: Correct previous patch regarding binlog-entry type. --- sql/sql_trigger.cc | 2 +- sql/sql_view.cc | 13 ++++++++++++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 61d2992ed1b..70053e54df0 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -284,7 +284,7 @@ end: thd->clear_error(); /* Such a statement can always go directly to binlog, no trans cache. */ - thd->binlog_query(THD::MYSQL_QUERY_TYPE, + thd->binlog_query(THD::MYSQL_STMT_TYPE, stmt_query.ptr(), stmt_query.length(), FALSE, FALSE); } } diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 79ecf12cf27..e3951e78df8 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1425,23 +1425,34 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) thd->query, thd->query_length, FALSE, FALSE); } - VOID(pthread_mutex_unlock(&LOCK_open)); if (error) { + VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(TRUE); } if (wrong_object_name) { + VOID(pthread_mutex_unlock(&LOCK_open)); my_error(ER_WRONG_OBJECT, MYF(0), wrong_object_db, wrong_object_name, "VIEW"); DBUG_RETURN(TRUE); } if (non_existant_views.length()) { + VOID(pthread_mutex_unlock(&LOCK_open)); my_error(ER_BAD_TABLE_ERROR, MYF(0), non_existant_views.c_ptr()); DBUG_RETURN(TRUE); } + + if (mysql_bin_log.is_open()) + { + thd->clear_error(); + thd->binlog_query(THD::STMT_QUERY_TYPE, + thd->query, thd->query_length, FALSE, FALSE); + } + send_ok(thd); + VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(FALSE); } From ec5bdb5185c791a94d4f68c0eff5345e282f1724 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 20 Oct 2006 22:21:05 -0400 Subject: [PATCH 181/235] Fix bad merge. --- sql/sql_trigger.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 70053e54df0..9dce838496d 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -284,7 +284,7 @@ end: thd->clear_error(); /* Such a statement can always go directly to binlog, no trans cache. */ - thd->binlog_query(THD::MYSQL_STMT_TYPE, + thd->binlog_query(THD::STMT_QUERY_TYPE, stmt_query.ptr(), stmt_query.length(), FALSE, FALSE); } } From f9223bc7e84d7143cac00153fe300ee635253404 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 10:56:13 +0200 Subject: [PATCH 182/235] Copy *.cnf file from std_data/ when doing a binary distribution --- scripts/make_binary_distribution.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/make_binary_distribution.sh b/scripts/make_binary_distribution.sh index b2eb9f3b727..d05c4427627 100644 --- a/scripts/make_binary_distribution.sh +++ b/scripts/make_binary_distribution.sh @@ -225,6 +225,7 @@ $CP mysql-test/lib/*.sql $BASE/mysql-test/lib $CP mysql-test/t/*.def $BASE/mysql-test/t $CP mysql-test/include/*.inc $BASE/mysql-test/include $CP mysql-test/std_data/*.dat mysql-test/std_data/*.*001 \ + mysql-test/std_data/*.cnf \ $BASE/mysql-test/std_data $CP mysql-test/std_data/des_key_file $BASE/mysql-test/std_data $CP mysql-test/t/*test mysql-test/t/*.opt mysql-test/t/*.slave-mi \ From e78a1931795d65e4b593f3016b37e8165cd26656 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 12:02:56 +0200 Subject: [PATCH 183/235] As both ndb and im are components that may be disabled as well as the binaries may not exist. Look for their binaries in a separate function and produce test casea failures for the test thet needs these components --- mysql-test/mysql-test-run.pl | 178 ++++++++++++++++++++++------------- 1 file changed, 115 insertions(+), 63 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7dac63b5373..acba4d843dd 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1295,6 +1295,54 @@ sub collect_mysqld_features () { } +sub executable_setup_im () { + + # Look for instance manager binary - mysqlmanager + $exe_im= + mtr_exe_maybe_exists( + "$glob_basedir/server-tools/instance-manager/mysqlmanager", + "$glob_basedir/libexec/mysqlmanager"); + + return ($exe_im eq ""); +} + +sub executable_setup_ndb () { + + # Look for ndb tols and binaries + my $ndb_path= mtr_file_exists("$glob_basedir/ndb", + "$glob_basedir/storage/ndb", + "$glob_basedir/bin"); + + $exe_ndbd= + mtr_exe_maybe_exists("$ndb_path/src/kernel/ndbd", + "$ndb_path/ndbd"); + $exe_ndb_mgm= + mtr_exe_maybe_exists("$ndb_path/src/mgmclient/ndb_mgm", + "$ndb_path/ndb_mgm"); + $exe_ndb_mgmd= + mtr_exe_maybe_exists("$ndb_path/src/mgmsrv/ndb_mgmd", + "$ndb_path/ndb_mgmd"); + $exe_ndb_waiter= + mtr_exe_maybe_exists("$ndb_path/tools/ndb_waiter", + "$ndb_path/ndb_waiter"); + + # May not exist + $path_ndb_tools_dir= mtr_file_exists("$ndb_path/tools", + "$ndb_path"); + # May not exist + $path_ndb_examples_dir= + mtr_file_exists("$ndb_path/ndbapi-examples", + "$ndb_path/examples"); + # May not exist + $exe_ndb_example= + mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + + return ( $exe_ndbd eq "" or + $exe_ndb_mgm eq "" or + $exe_ndb_mgmd eq "" or + $exe_ndb_waiter eq ""); +} + sub executable_setup () { # @@ -1333,20 +1381,6 @@ sub executable_setup () { "$glob_basedir/extra/release/perror", "$glob_basedir/extra/debug/perror"); - - if ( ! $opt_skip_im ) - { - # Look for instance manager binary - mysqlmanager - $exe_im= - mtr_exe_exists( - "$glob_basedir/server-tools/instance-manager/mysqlmanager", - "$glob_basedir/libexec/mysqlmanager"); - } - else - { - $exe_im= "not_available"; - } - # Look for the client binaries $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); $exe_mysqldump= mtr_exe_exists("$path_client_bindir/mysqldump"); @@ -1368,35 +1402,25 @@ sub executable_setup () { "$path_client_bindir/mysql_fix_privilege_tables"); } - if ( ! $opt_skip_ndbcluster) + + if ( ! $opt_skip_ndbcluster and executable_setup_ndb()) { - # Look for ndb tols and binaries - my $ndb_path= mtr_path_exists("$glob_basedir/ndb", - "$glob_basedir/storage/ndb", - "$glob_basedir/bin"); + mtr_warning("Could not find all required ndb binaries, " . + "all ndb tests will fail, use --skip-ndbcluster to " . + "skip testing it."); - $path_ndb_tools_dir= mtr_path_exists("$ndb_path/tools", - "$ndb_path"); - $exe_ndb_mgm= - mtr_exe_exists("$ndb_path/src/mgmclient/ndb_mgm", - "$ndb_path/ndb_mgm"); - $exe_ndb_mgmd= - mtr_exe_exists("$ndb_path/src/mgmsrv/ndb_mgmd", - "$ndb_path/ndb_mgmd"); - $exe_ndb_waiter= - mtr_exe_exists("$ndb_path/tools/ndb_waiter", - "$ndb_path/ndb_waiter"); - $exe_ndbd= - mtr_exe_exists("$ndb_path/src/kernel/ndbd", - "$ndb_path/ndbd"); + foreach my $cluster (@{$clusters}) + { + $cluster->{"executable_setup_failed"}= 1; + } + } - # May not exist - $path_ndb_examples_dir= - mtr_file_exists("$ndb_path/ndbapi-examples", - "$ndb_path/examples"); - # May not exist - $exe_ndb_example= - mtr_file_exists("$path_ndb_examples_dir/ndbapi_simple/ndbapi_simple"); + if ( ! $opt_skip_im and executable_setup_im()) + { + mtr_warning("Could not find all required instance manager binaries, " . + "all im tests will fail, use --skip-im to " . + "continue without instance manager"); + $instance_manager->{"executable_setup_failed"}= 1; } # Look for the udf_example library @@ -1424,7 +1448,8 @@ sub executable_setup () { if ( $glob_use_embedded_server ) { $exe_mysql_client_test= - mtr_exe_maybe_exists("$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); + mtr_exe_maybe_exists( + "$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); } else { @@ -1567,19 +1592,28 @@ sub environment_setup () { # ---------------------------------------------------- # Setup env for IM # ---------------------------------------------------- - $ENV{'IM_EXE'}= $exe_im; - $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid}; - $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid}; - $ENV{'IM_PORT'}= $instance_manager->{port}; - $ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file}; - $ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file}; + if ( ! $opt_skip_im ) + { + $ENV{'IM_EXE'}= $exe_im; + $ENV{'IM_PATH_PID'}= $instance_manager->{path_pid}; + $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid}; + $ENV{'IM_PORT'}= $instance_manager->{port}; + $ENV{'IM_DEFAULTS_PATH'}= $instance_manager->{defaults_file}; + $ENV{'IM_PASSWORD_PATH'}= $instance_manager->{password_file}; - $ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock}; - $ENV{'IM_MYSQLD1_PORT'}= $instance_manager->{instances}->[0]->{port}; - $ENV{'IM_MYSQLD1_PATH_PID'}=$instance_manager->{instances}->[0]->{path_pid}; - $ENV{'IM_MYSQLD2_SOCK'}= $instance_manager->{instances}->[1]->{path_sock}; - $ENV{'IM_MYSQLD2_PORT'}= $instance_manager->{instances}->[1]->{port}; - $ENV{'IM_MYSQLD2_PATH_PID'}=$instance_manager->{instances}->[1]->{path_pid}; + $ENV{'IM_MYSQLD1_SOCK'}= + $instance_manager->{instances}->[0]->{path_sock}; + $ENV{'IM_MYSQLD1_PORT'}= + $instance_manager->{instances}->[0]->{port}; + $ENV{'IM_MYSQLD1_PATH_PID'}= + $instance_manager->{instances}->[0]->{path_pid}; + $ENV{'IM_MYSQLD2_SOCK'}= + $instance_manager->{instances}->[1]->{path_sock}; + $ENV{'IM_MYSQLD2_PORT'}= + $instance_manager->{instances}->[1]->{port}; + $ENV{'IM_MYSQLD2_PATH_PID'}= + $instance_manager->{instances}->[1]->{path_pid}; + } # ---------------------------------------------------- # Setup env so childs can execute mysqlcheck @@ -2037,14 +2071,6 @@ sub check_ndbcluster_support ($) { $opt_skip_ndbcluster_slave= 1; return; } - elsif ( -e "$glob_basedir/bin" && ! -f "$glob_basedir/bin/ndbd") - { - # Binary dist with a mysqld that supports ndb, but no ndbd found - mtr_report("Skipping ndbcluster, can't fint binaries"); - $opt_skip_ndbcluster= 1; - $opt_skip_ndbcluster_slave= 1; - return; - } $glob_ndbcluster_supported= 1; mtr_report("Using ndbcluster when necessary, mysqld supports it"); @@ -2475,7 +2501,8 @@ sub mysql_install_db () { my $cluster_started_ok= 1; # Assume it can be started - if ($opt_skip_ndbcluster || $glob_use_running_ndbcluster) + if ($opt_skip_ndbcluster || $glob_use_running_ndbcluster || + $clusters->[0]->{executable_setup_failed}) { # Don't install master cluster } @@ -2486,7 +2513,8 @@ sub mysql_install_db () { } if ($max_slave_num == 0 || - $opt_skip_ndbcluster_slave || $glob_use_running_ndbcluster_slave) + $opt_skip_ndbcluster_slave || $glob_use_running_ndbcluster_slave || + $clusters->[1]->{executable_setup_failed}) { # Don't install slave cluster } @@ -2760,6 +2788,16 @@ sub run_testcase_check_skip_test($) last if ($opt_skip_ndbcluster_slave and $cluster->{'name'} eq 'Slave'); + # If test needs this cluster, check binaries was found ok + if ( $cluster->{'executable_setup_failed'} ) + { + mtr_report_test_name($tinfo); + $tinfo->{comment}= + "Failed to find cluster binaries"; + mtr_report_test_failed($tinfo); + return 1; + } + # If test needs this cluster, check it was installed ok if ( !$cluster->{'installed_ok'} ) { @@ -2769,6 +2807,20 @@ sub run_testcase_check_skip_test($) mtr_report_test_failed($tinfo); return 1; } + + } + } + + if ( $tinfo->{'component_id'} eq 'im' ) + { + # If test needs im, check binaries was found ok + if ( $instance_manager->{'executable_setup_failed'} ) + { + mtr_report_test_name($tinfo); + $tinfo->{comment}= + "Failed to find MySQL manager binaries"; + mtr_report_test_failed($tinfo); + return 1; } } From 788968a61b5a9a80d8716cacb2f28a36c8c29bcf Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 12:16:40 +0200 Subject: [PATCH 184/235] If "var" is a symlink which does not point to anything, remove it before creating real var mysql-test/mysql-test-run.pl: If "var" is a symlink which does not point to anything, remove it --- mysql-test/mysql-test-run.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index acba4d843dd..f429bac850d 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1868,6 +1868,11 @@ sub kill_running_servers () { if ( ! -d $opt_vardir ) { + if ( -l $opt_vardir and ! -d readlink($opt_vardir) ) + { + mtr_report("Removing $opt_vardir symlink without destination"); + unlink($opt_vardir); + } # The "var" dir does not exist already # the processes that mtr_kill_leftovers start will write # their log files to var/log so it should be created From 88e5b3166dc4eb17bd4517fa47346ea2f6fefe4d Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 12:56:25 +0200 Subject: [PATCH 185/235] When looking for libc the path need to be converted from wine to unix format before test that directory exists --- netware/BUILD/mwenv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index bc797c442ab..a60da17d987 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -27,8 +27,8 @@ WINE_BUILD_DIR="$base/$WINE_BUILD_DIR" echo "WINE_BUILD_DIR: $WINE_BUILD_DIR" # Look for libc, MySQL 5.0.x uses libc-2003 by default -libcdir="$MYDEV/libc-2003" -if test ! -d $libcdir +libc_dir="$MYDEV/libc-2003" +if [ ! -d `winepath $libc_dir` ] then # The libcdir didn't exist, set default libc_dir="$MYDEV/libc" From 29947efc6257e3348b00363c4a4ab301249588b3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 13:12:30 +0200 Subject: [PATCH 186/235] Fix for bug#23037 Bug in field "Default" of query "SHOW COLUMNS FROM table" To the documentor: The DEFAULT value in SHOW COLUMNS/SELECT FROM I_S.COLUMNS was truncated to NAME_LEN (which effectively is 64) characters. mysql-test/r/information_schema.result: Update result Because the length of I_S.COLUMNS.COLUMN_DEFAULT was increased to 65535 the column changed it's type from varchar(64) to longtext The type is longtext if the length is > 65532 (the max varchar len) mysql-test/t/information_schema.test: test case for bug#23037: Bug in field "Default" of query "SHOW COLUMNS FROM table" Both SHOW COLUMNS and I_S.COLUMNS is TESTED as well the value returned by both. Using --replace_regex is unfeasible as the repetition value cannot be > 255. --replace_regex /A{256}/VALUE/ doesn't work, not to talk about /A{65532}/VALUE/ /(A{255}){255}/VALUE/ is awfully slow. Thus, simple function with cursor is used to extract the value. sql/sql_show.cc: Default value can have TIMESTAMP, CHAR, VARCHAR, ENUM VARCHAR can have the longest value, up to 65535. However, because of table handler limitations the actual limit is 65532 characters, latin1 charset. However, here is used MAX_FIELD_VARCHARLENGTH macro, because there could be a storage engine without such limitation. --- mysql-test/r/information_schema.result | 14 +++++++++ mysql-test/t/information_schema.test | 43 ++++++++++++++++++++++++++ sql/sql_show.cc | 2 +- 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 407f8a040b7..3fffce73aa9 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -737,6 +737,7 @@ select table_schema,table_name, column_name from information_schema.columns where data_type = 'longtext'; table_schema table_name column_name +information_schema COLUMNS COLUMN_DEFAULT information_schema COLUMNS COLUMN_TYPE information_schema ROUTINES ROUTINE_DEFINITION information_schema ROUTINES SQL_MODE @@ -1240,3 +1241,16 @@ WHERE table_name=(SELECT MAX(table_name) FROM information_schema.tables); table_name VIEWS +DROP TABLE IF EXISTS bug23037; +DROP FUNCTION IF EXISTS get_value; +SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037'; +COLUMN_NAME MD5(COLUMN_DEFAULT) LENGTH(COLUMN_DEFAULT) +fld1 7cf7a6782be951a1f2464a350da926a5 65532 +SELECT MD5(get_value()); +MD5(get_value()) +7cf7a6782be951a1f2464a350da926a5 +SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT), COLUMN_DEFAULT=get_value() FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037'; +COLUMN_NAME MD5(COLUMN_DEFAULT) LENGTH(COLUMN_DEFAULT) COLUMN_DEFAULT=get_value() +fld1 7cf7a6782be951a1f2464a350da926a5 65532 1 +DROP TABLE bug23037; +DROP FUNCTION get_value; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 9e5dac8b853..27007bbe16a 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -930,4 +930,47 @@ SELECT table_name from information_schema.tables WHERE table_name=(SELECT MAX(table_name) FROM information_schema.tables); +# +# Bug #23037: Bug in field "Default" of query "SHOW COLUMNS FROM table" +# +# Note, MyISAM/InnoDB can't take more that 65532 chars, because the row +# size is limited to 65535 bytes (BLOBs not counted) +# +--disable_warnings +DROP TABLE IF EXISTS bug23037; +DROP FUNCTION IF EXISTS get_value; +--enable_warnings +--disable_query_log +DELIMITER |; +CREATE FUNCTION get_value() + RETURNS TEXT + DETERMINISTIC +BEGIN + DECLARE col1, col2, col3, col4, col6 CHAR(255); + DECLARE default_val VARCHAR(65532); + DECLARE done INT DEFAULT 0; + DECLARE cur1 CURSOR FOR SHOW COLUMNS FROM bug23037; + DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1; + OPEN cur1; + FETCH cur1 INTO col1, col2, col3, col4, default_val, col6; + CLOSE cur1; + RETURN default_val; +end| +DELIMITER ;| + +let $body=`SELECT REPEAT('A', 65532)`; +eval CREATE TABLE bug23037(fld1 VARCHAR(65532) CHARACTER SET latin1 DEFAULT "$body"); +--enable_query_log + +SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT) FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037'; + +SELECT MD5(get_value()); + +SELECT COLUMN_NAME, MD5(COLUMN_DEFAULT), LENGTH(COLUMN_DEFAULT), COLUMN_DEFAULT=get_value() FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='bug23037'; + +DROP TABLE bug23037; +DROP FUNCTION get_value; + + + # End of 5.0 tests. diff --git a/sql/sql_show.cc b/sql/sql_show.cc index eb78f4fbdae..ba9a089e782 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4044,7 +4044,7 @@ ST_FIELD_INFO columns_fields_info[]= {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"COLUMN_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Field"}, {"ORDINAL_POSITION", 21 , MYSQL_TYPE_LONG, 0, 0, 0}, - {"COLUMN_DEFAULT", NAME_LEN, MYSQL_TYPE_STRING, 0, 1, "Default"}, + {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0, 1, "Default"}, {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null"}, {"DATA_TYPE", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, 0}, {"CHARACTER_MAXIMUM_LENGTH", 21 , MYSQL_TYPE_LONG, 0, 1, 0}, From 394b27b6b415f0042829d99ba6557e3c5db6e601 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 13:26:04 +0200 Subject: [PATCH 187/235] Netware uses size_t as socklen_t --- extra/yassl/testsuite/test.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/extra/yassl/testsuite/test.hpp b/extra/yassl/testsuite/test.hpp index 0266c802657..b23b36f0ba2 100644 --- a/extra/yassl/testsuite/test.hpp +++ b/extra/yassl/testsuite/test.hpp @@ -27,9 +27,12 @@ #endif /* _WIN32 */ -#if !defined(_SOCKLEN_T) && (defined(_WIN32) || defined(__NETWARE__)) +#if !defined(_SOCKLEN_T) && defined(_WIN32) typedef int socklen_t; #endif +#if !defined(_SOCKLEN_T) && defined(__NETWARE__) + typedef size_t socklen_t; +#endif // Check type of third arg to accept From edf668e8fa76fe4558c43d54308c6a0cad59e325 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 13:32:20 +0200 Subject: [PATCH 188/235] Don't use the "4.1 vardir trick" on OS that does not have native symlink(i.e windows) --- mysql-test/mysql-test-run.pl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f429bac850d..c36a06f56ef 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -758,7 +758,8 @@ sub command_line_setup () { $opt_vardir= $default_vardir; } elsif ( $mysql_version_id < 50000 and - $opt_vardir ne $default_vardir ) + ! $glob_win32 and # No supported on platforms without native symlink + $opt_vardir ne $default_vardir) { # Version 4.1 and --vardir was specified # Only supported as a symlink from var/ From 9655547b8793cbfe95f0238cc9c33fabb279286e Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 15:11:24 +0200 Subject: [PATCH 189/235] after merge fix --- mysql-test/r/information_schema.result | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index a2754e7a92e..305e89f0325 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -759,6 +759,7 @@ select table_schema,table_name, column_name from information_schema.columns where data_type = 'longtext'; table_schema table_name column_name +information_schema COLUMNS COLUMN_DEFAULT information_schema COLUMNS COLUMN_TYPE information_schema EVENTS EVENT_DEFINITION information_schema EVENTS SQL_MODE From 13c55f3c1783d8820ad6f2c538a187b371b3017a Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 16:51:48 +0200 Subject: [PATCH 190/235] The vardir trick can only bge used on platforms with native symlinks - otherwise opt_vardir need to be set to default value. --- mysql-test/mysql-test-run.pl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index c36a06f56ef..84d84cf8f14 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -758,15 +758,19 @@ sub command_line_setup () { $opt_vardir= $default_vardir; } elsif ( $mysql_version_id < 50000 and - ! $glob_win32 and # No supported on platforms without native symlink $opt_vardir ne $default_vardir) { # Version 4.1 and --vardir was specified # Only supported as a symlink from var/ # by setting up $opt_mem that symlink will be created - $opt_mem= $opt_vardir; + if ( ! $glob_win32 ) + { + # Only platforms that have native symlinks can use the vardir trick + $opt_mem= $opt_vardir; + mtr_report("Using 4.1 vardir trick"); + } + $opt_vardir= $default_vardir; - mtr_report("Using 4.1 vardir trick"); } $path_vardir_trace= $opt_vardir; From f9ff7472a23d97cc7235b5396191b02aad37fc21 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 23 Oct 2006 20:36:44 +0200 Subject: [PATCH 191/235] Avoid matching the trailing carriage return when parsing the mysqld.spec file This fixes problem where --replace_result failed in rpl000015 because the MYSQL_TCP_PORT variable was "3306\r" mysql-test/mysql-test-run.pl: Avoid matching the trailing carriage return when parsing the mysqld.spec file --- mysql-test/mysql-test-run.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 84d84cf8f14..7f1f7a43b10 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1269,9 +1269,9 @@ sub collect_mysqld_features () { else { # Put variables into hash - if ( $line =~ /^([\S]+)[ \t]+(.*)$/ ) + if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) { - # print "$1=$2\n"; + # print "$1=\"$2\"\n"; $mysqld_variables{$1}= $2; } else From 0b381c94cb262958fa672f00c308099b227c1fbe Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 10:43:15 +0200 Subject: [PATCH 192/235] When using yaSSL on NetWare some of the OpenSSL specifix hacks can be skipped vio/viossl.c: No need for special code to switch from WinSock to BSD sockets when using yaSSL vio/viosslfactories.c: The OpenSSL port to NetWare has added some extra functions to free up memory, no need to call them when using yaSSL --- vio/viossl.c | 5 +++++ vio/viosslfactories.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/vio/viossl.c b/vio/viossl.c index 9cc4523d32e..b5fd0e11c02 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -26,6 +26,10 @@ #ifdef HAVE_OPENSSL #ifdef __NETWARE__ + +/* yaSSL already uses BSD sockets */ +#ifndef HAVE_YASSL + /* The default OpenSSL implementation on NetWare uses WinSock. This code allows us to use the BSD sockets. @@ -47,6 +51,7 @@ static int SSL_set_fd_bsd(SSL *s, int fd) #define SSL_set_fd(A, B) SSL_set_fd_bsd((A), (B)) +#endif /* HAVE_YASSL */ #endif /* __NETWARE__ */ diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 2c528e9a2fc..9fd18579351 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -180,11 +180,15 @@ void netware_ssl_cleanup() /* free memory from SSL_library_init() */ EVP_cleanup(); +/* OpenSSL NetWare port specific functions */ +#ifndef HAVE_YASSL + /* free global X509 method */ X509_STORE_method_cleanup(); /* free the thread_hash error table */ ERR_free_state_table(); +#endif } From 375b04b9fe8826bd666b49421b5176a9316039e8 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 11:16:53 +0200 Subject: [PATCH 193/235] Temporary fixes for building from source dist in pushbuild netware/BUILD/compile-netware-END: If running as user pushbuild don't run autotools again netware/BUILD/mwenv: Set ARFLAGS to value of AR_FLAGS --- netware/BUILD/compile-netware-END | 9 +++++++-- netware/BUILD/mwenv | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/netware/BUILD/compile-netware-END b/netware/BUILD/compile-netware-END index a8d829499bd..6c531ab5c7c 100755 --- a/netware/BUILD/compile-netware-END +++ b/netware/BUILD/compile-netware-END @@ -18,8 +18,13 @@ rm -rf Makefile.in.bk # Setup Metrowerks environment . $path/mwenv -# Run autotools(use BUILD/autorun.sh) -. BUILD/autorun.sh +# Temporary hack to allow building from source dist +if [ ! "$USER"=pushbuild ] +then + # Run autotools(use BUILD/autorun.sh) + echo "Running autotools again(BUILD/autorun.sh)" + . BUILD/autorun.sh +fi # configure ./configure $base_configs $extra_configs diff --git a/netware/BUILD/mwenv b/netware/BUILD/mwenv index a60da17d987..a8d31949736 100755 --- a/netware/BUILD/mwenv +++ b/netware/BUILD/mwenv @@ -65,5 +65,11 @@ then export TERM=linux fi +# Temporary hack to allow building from source dist +if [ "$USER"=pushbuild ] +then + export ARFLAGS=$AR_FLAGS +fi + # Print all env. variables export From b0626431808b30a4dac6f5442157ad878c8caa93 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 13:12:34 +0200 Subject: [PATCH 194/235] Replace all refernces to .la libraries with direct references to their .libs/*.a library Add comment describing why mwldnlm is called with "x" flag configure.in: Replace references to yassl .la libraries with direct reference to the .a libraries netware/BUILD/mwldnlm: Add comment about why mwldnlm is called with the "x" flag and how to avoid it --- configure.in | 4 ++++ netware/BUILD/mwldnlm | 7 +++++++ 2 files changed, 11 insertions(+) diff --git a/configure.in b/configure.in index 55da1dfb241..c050d31a917 100644 --- a/configure.in +++ b/configure.in @@ -1176,12 +1176,16 @@ EOF cat > $filesed << EOF s,\(\./conf_to_src\)\( \$(top_srcdir)\),\1.linux\2, s,\(: conf_to_src\),\1.linux, +s,libyassl.la,.libs/libyassl.a, +s,libtaocrypt.la,.libs/libtaocrypt.a, EOF ;; libmysql_r/Makefile.in) cat > $filesed << EOF s,\(\./conf_to_src\)\( \$(top_srcdir)\),\1.linux\2, s,\(: conf_to_src\),\1.linux, +s,libyassl.la,.libs/libyassl.a, +s,libtaocrypt.la,.libs/libtaocrypt.a, EOF ;; strings/Makefile.in) diff --git a/netware/BUILD/mwldnlm b/netware/BUILD/mwldnlm index cc8c9e63c6e..b1822827b59 100755 --- a/netware/BUILD/mwldnlm +++ b/netware/BUILD/mwldnlm @@ -3,6 +3,13 @@ # stop on errors set -e +# If libtool passes "x" as the first argument to this script +# it's an indication that libtool is trying to unpack .la's +# so they can be added to a new library +# This step does not work on Netware and we avoid it by +# replacing the .la library with the path to the .a library +# in Makefile.in + args=" $*" # NOTE: Option 'pipefail' is not standard sh From 7e1fcb649f9e2e7a113da14db8bd290c8dc97f66 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 13:34:10 +0200 Subject: [PATCH 195/235] Enable the ATTRIBUTE_FORMAT macros to check format of variable arg parameters --- client/mysqltest.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 5bc132a874f..9f41586afae 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -398,13 +398,13 @@ TYPELIB command_typelib= {array_elements(command_names),"", DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages; void die(const char *fmt, ...) - /* ATTRIBUTE_FORMAT(printf, 1, 2) */; + ATTRIBUTE_FORMAT(printf, 1, 2); void abort_not_supported_test(const char *fmt, ...) - /* ATTRIBUTE_FORMAT(printf, 1, 2) */; + ATTRIBUTE_FORMAT(printf, 1, 2); void verbose_msg(const char *fmt, ...) - /* ATTRIBUTE_FORMAT(printf, 1, 2) */; + ATTRIBUTE_FORMAT(printf, 1, 2); void warning_msg(const char *fmt, ...) - /* ATTRIBUTE_FORMAT(printf, 1, 2) */; + ATTRIBUTE_FORMAT(printf, 1, 2); VAR* var_from_env(const char *, const char *); VAR* var_init(VAR* v, const char *name, int name_len, const char *val, From 8b3f82322eafdd369861f52eaef95ee26780cf70 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 13:52:50 +0200 Subject: [PATCH 196/235] Use same type for local variables as arguments, avoid compile error on NetWare --- client/mysqldump.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/mysqldump.c b/client/mysqldump.c index 28a220bf61e..757bec09b50 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -1195,7 +1195,7 @@ static void print_xml_tag(FILE * xml_file, const char* sbeg, const char* send, const char* first_attribute_name, ...) { va_list arg_list; - char *attribute_name, *attribute_value; + const char *attribute_name, *attribute_value; fputs(sbeg, xml_file); fputc('<', xml_file); @@ -1318,7 +1318,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name, static void print_blob_as_hex(FILE *output_file, const char *str, ulong len) { /* sakaik got the idea to to provide blob's in hex notation. */ - char *ptr= str, *end= ptr + len; + const char *ptr= str, *end= ptr + len; for (; ptr < end ; ptr++) fprintf(output_file, "%02X", *((uchar *)ptr)); check_io(output_file); From e3936b1065c501e958986ab70c1bebc24785de19 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 17:36:46 +0200 Subject: [PATCH 197/235] Add analyze_testcase_failure which is called when mysqltest has failed with error 1 and we are running with --force The specific "analyze" code is enclosed in a .test file fwich can easily be modified to be more advanced mysql-test/mysql-test-run.pl: Attempt to run some quick queries to analyze the failure when mysqltest returns 1 indicating test has failed Initially only code to analyze "could not sync with master" is added as that is a blackbox and all problems looks the same mysql-test/include/analyze_failure_sync_with_master.test: New BitKeeper file ``mysql-test/include/analyze_failure_sync_with_master.test'' --- .../analyze_failure_sync_with_master.test | 15 +++++ mysql-test/mysql-test-run.pl | 56 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 mysql-test/include/analyze_failure_sync_with_master.test diff --git a/mysql-test/include/analyze_failure_sync_with_master.test b/mysql-test/include/analyze_failure_sync_with_master.test new file mode 100644 index 00000000000..e6fd32d2f46 --- /dev/null +++ b/mysql-test/include/analyze_failure_sync_with_master.test @@ -0,0 +1,15 @@ +# Connect to both master and slave +connect (master,127.0.0.1,root,,test,$MASTER_MYPORT,); +connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT,); + +vertical_results; + +echo == MASTER ===========================================================; +connection master; +show master status; +show slave status; + +echo == SLAVE ===========================================================; +connection slave; +show master status; +show slave status; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 7f1f7a43b10..f88cd333b91 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2923,6 +2923,58 @@ sub find_testcase_skipped_reason($) } +sub analyze_testcase_failure_sync_with_master($) +{ + my ($tinfo)= @_; + mtr_verbose("analyze_testcase_failure_sync_with_master"); + print "analyze_testcase_failure_sync_with_master\n"; + + my $args; + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--silent"); + mtr_add_arg($args, "-v"); + mtr_add_arg($args, "--skip-safemalloc"); + mtr_add_arg($args, "--tmpdir=%s", $opt_tmpdir); + + mtr_add_arg($args, "--socket=%s", $master->[0]->{'path_sock'}); + mtr_add_arg($args, "--port=%d", $master->[0]->{'port'}); + mtr_add_arg($args, "--database=test"); + mtr_add_arg($args, "--user=%s", $opt_user); + mtr_add_arg($args, "--password="); + + # Run the test file and append output to log file + mtr_run_test($exe_mysqltest,$args, + "include/analyze_failure_sync_with_master.test", + "$path_timefile", "$path_timefile","", + { append_log_file => 1 }); + +} + +sub analyze_testcase_failure($) +{ + my ($tinfo)= @_; + + # Open mysqltest.log + my $F= IO::File->new($path_timefile) or + mtr_error("can't open file \"$path_timefile\": $!"); + + while ( my $line= <$F> ) + { + # Look for "mysqltest: At line nnn: + if ( $line =~ /mysqltest: At line [0-9]*: (.*)/ ) + { + my $error= $1; + # Look for "could not sync with master" + if ( $error =~ /could not sync with master/ ) + { + analyze_testcase_failure_sync_with_master($tinfo); + } + } + } +} + ############################################################################## # # Run a single test case @@ -3011,6 +3063,10 @@ sub run_testcase ($) { } elsif ( $res == 1 ) { + if ( $opt_force ) + { + analyze_testcase_failure($tinfo); + } # Test case failure reported by mysqltest report_failure_and_restart($tinfo); } From 1023e010587c63e3a7fb04b3dea804de5e556468 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 17:54:45 +0200 Subject: [PATCH 198/235] Fix spelling errors in test files mysql-test/r/mysqldump-max.result: Update test result after fix of spelling error mysql-test/r/rpl_trigger.result: Update test result after fix of spelling error mysql-test/r/type_newdecimal.result: Update test result after fix of spelling error mysql-test/t/mysqldump-max.test: Fix spelling error "disable_warnings" Write shorter "drop table..." mysql-test/t/rpl_trigger.test: Fix spelling error, there is no --ignore_warnings mysql-test/t/type_newdecimal.test: Fix spelling error --- mysql-test/r/mysqldump-max.result | 19 +------------------ mysql-test/r/rpl_trigger.result | 2 -- mysql-test/r/type_newdecimal.result | 2 -- mysql-test/t/mysqldump-max.test | 11 +++-------- mysql-test/t/rpl_trigger.test | 2 +- mysql-test/t/type_newdecimal.test | 4 ++-- 6 files changed, 7 insertions(+), 33 deletions(-) diff --git a/mysql-test/r/mysqldump-max.result b/mysql-test/r/mysqldump-max.result index 78867d1e430..9ae3e368e28 100644 --- a/mysql-test/r/mysqldump-max.result +++ b/mysql-test/r/mysqldump-max.result @@ -1,21 +1,4 @@ -drop table if exists t1; -Warnings: -Note 1051 Unknown table 't1' -drop table if exists t2; -Warnings: -Note 1051 Unknown table 't2' -drop table if exists t3; -Warnings: -Note 1051 Unknown table 't3' -drop table if exists t4; -Warnings: -Note 1051 Unknown table 't4' -drop table if exists t5; -Warnings: -Note 1051 Unknown table 't5' -drop table if exists t6; -Warnings: -Note 1051 Unknown table 't6' +drop table if exists t1, t2, t3, t4, t5, t6; create table t1 (id int(8), name varchar(32)); create table t2 (id int(8), name varchar(32)) ENGINE="MyISAM"; create table t3 (id int(8), name varchar(32)) ENGINE="MEMORY"; diff --git a/mysql-test/r/rpl_trigger.result b/mysql-test/r/rpl_trigger.result index 49f0f5c4c44..3c740bf8e64 100644 --- a/mysql-test/r/rpl_trigger.result +++ b/mysql-test/r/rpl_trigger.result @@ -71,8 +71,6 @@ get_lock("bug12480",2) 1 create table t1 (a datetime,b datetime, c datetime); drop function if exists bug12480; -Warnings: -Note 1305 FUNCTION bug12480 does not exist create function bug12480() returns datetime begin set @a=get_lock("bug12480",2); diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index 33f1ece0390..84d2ea47298 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -978,8 +978,6 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; drop procedure if exists wg2; -Warnings: -Note 1305 PROCEDURE wg2 does not exist create procedure wg2() begin declare v int default 1; diff --git a/mysql-test/t/mysqldump-max.test b/mysql-test/t/mysqldump-max.test index fbea84808b4..359c4ea5793 100644 --- a/mysql-test/t/mysqldump-max.test +++ b/mysql-test/t/mysqldump-max.test @@ -3,14 +3,9 @@ --source include/have_innodb.inc --source include/have_archive.inc ---disable-warnings -drop table if exists t1; -drop table if exists t2; -drop table if exists t3; -drop table if exists t4; -drop table if exists t5; -drop table if exists t6; ---enable-warnings +--disable_warnings +drop table if exists t1, t2, t3, t4, t5, t6; +--enable_warnings create table t1 (id int(8), name varchar(32)); create table t2 (id int(8), name varchar(32)) ENGINE="MyISAM"; diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test index 3c8cbb97b31..d6e9410b1d3 100644 --- a/mysql-test/t/rpl_trigger.test +++ b/mysql-test/t/rpl_trigger.test @@ -62,7 +62,7 @@ select get_lock("bug12480",2); connection default; create table t1 (a datetime,b datetime, c datetime); ---ignore_warnings +--disable_warnings drop function if exists bug12480; --enable_warnings diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index de1ebd74d17..e4843c3b83e 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -1000,9 +1000,9 @@ drop table t1; # # Bug 12938 (arithmetic loop's zero) # ---disable-warnings +--disable_warnings drop procedure if exists wg2; ---enable-warnings +--enable_warnings delimiter //; create procedure wg2() begin From c58d8ffb4fd7eb86b663fd8f3831af70b5785cfb Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 18:21:23 +0200 Subject: [PATCH 199/235] Test "rpl_ndb_auto_inc" need ndb - add "include/have_ndb.inc" mysql-test/t/rpl_ndb_auto_inc.test: Test need ndb --- mysql-test/t/rpl_ndb_auto_inc.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/rpl_ndb_auto_inc.test b/mysql-test/t/rpl_ndb_auto_inc.test index 0fc31de9b3a..53bb7e764f1 100644 --- a/mysql-test/t/rpl_ndb_auto_inc.test +++ b/mysql-test/t/rpl_ndb_auto_inc.test @@ -6,6 +6,7 @@ # Date: 2006-02-10 # Change: Augmented test to use with cluster ##################################### +--source include/have_ndb.inc --source include/master-slave.inc --source include/have_binlog_format_mixed_or_row.inc From 297d968a8c5b313c139c6d96b8bd26b57a7dc64c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 18:49:19 +0200 Subject: [PATCH 200/235] Run mysql_client_test without --silent Flush both stdout and stderr before abort'ing mysql_client_test mysql-test/mysql-test-run.pl: Run mysql_client_test wihtout --silent flag tests/mysql_client_test.c: Before aborting mysql_client_test in die, make sure to first flush stdout and finally after the error message has been printed also fflush stderr --- mysql-test/mysql-test-run.pl | 2 +- tests/mysql_client_test.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index f88cd333b91..731d07c86c5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1735,7 +1735,7 @@ sub environment_setup () { # Setup env so childs can execute mysql_client_test # ---------------------------------------------------- my $cmdline_mysql_client_test= - "$exe_mysql_client_test --no-defaults --testcase --user=root --silent " . + "$exe_mysql_client_test --no-defaults --testcase --user=root " . "--port=$master->[0]->{'port'} " . "--socket=$master->[0]->{'path_sock'}"; if ( $mysql_version_id >= 50000 ) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 9fabde993b8..64c260666d3 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -113,7 +113,9 @@ static void client_disconnect(); void die(const char *file, int line, const char *expr) { + fflush(stdout); fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr); + fflush(stderr); abort(); } From 7941fdd0271e5e772d925105aefe283b03ab1ba0 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 19:16:18 +0200 Subject: [PATCH 201/235] Bug#23037 Bug in field "Default" of query "SHOW COLUMNS FROM table" - Fix check in mysql_client_test to reflect the change of datatype for DEFAULT column tests/mysql_client_test.c: Update check of datatype for field DEFAULT returned from "explain" as datatype has changed after patch for bug 23037 --- tests/mysql_client_test.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 5a718b7bde9..96fdb9a4696 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -7497,10 +7497,22 @@ static void test_explain_bug() MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, 0, 0, "", 3, 0); - verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT", - mysql_get_server_version(mysql) <= 50000 ? - MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, - 0, 0, "", 64, 0); + if ( mysql_get_server_version(mysql) >= 50027 ) + { + /* The patch for bug#23037 changes column type of DEAULT to blob */ + verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT", + MYSQL_TYPE_BLOB, 0, 0, "", 0, 0); + } + else + { + verify_prepare_field(result, 4, "Default", "COLUMN_DEFAULT", + mysql_get_server_version(mysql) >= 50027 ? + MYSQL_TYPE_BLOB : + mysql_get_server_version(mysql) <= 50000 ? + MYSQL_TYPE_STRING : MYSQL_TYPE_VAR_STRING, + 0, 0, "", + mysql_get_server_version(mysql) >= 50027 ? 0 :64, 0); + } verify_prepare_field(result, 5, "Extra", "EXTRA", mysql_get_server_version(mysql) <= 50000 ? From c7cedcd645703c80b076bae316affa23cee5bf73 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 19:22:27 +0200 Subject: [PATCH 202/235] Remove debug printout --- mysql-test/mysql-test-run.pl | 2 -- 1 file changed, 2 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 731d07c86c5..3046e5ba2fe 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2926,8 +2926,6 @@ sub find_testcase_skipped_reason($) sub analyze_testcase_failure_sync_with_master($) { my ($tinfo)= @_; - mtr_verbose("analyze_testcase_failure_sync_with_master"); - print "analyze_testcase_failure_sync_with_master\n"; my $args; mtr_init_args(\$args); From 9c9bf0aff21df3ec9395d124f72fc1eeb17c2c16 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 20:32:07 +0200 Subject: [PATCH 203/235] WL#3462 Add testing of MySQL client ABI to prevent unintentional ABI breaks BUG#23427 incompatible ABI change in 5.0.26? - Use the icheck tool if avaliable and compare the current mysql.h to a version controlled reference file BitKeeper/etc/ignore: Added include/check_abi include/mysql_h.ic to the ignore list configure.in: Look for icheck in configure include/Makefile.am: Add rule to build mysql_h.ic if icheck is avaliable Add rule to compare mysql_h.ic to the version controlled reference file mysql_h_abi.ic include/mysql.h: Add comment about taking care when editing mysql.h Add example how to add reserved fiels in the structs to allow for features to be added without breaking ABI include/mysql_h_abi.ic: Add new file describing the libmysqlclient ABI used as a reference to detect ABI breakage --- .bzrignore | 2 + configure.in | 4 + include/Makefile.am | 28 +- include/mysql.h | 11 + include/mysql_h_abi.ic | 1244 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 1287 insertions(+), 2 deletions(-) create mode 100644 include/mysql_h_abi.ic diff --git a/.bzrignore b/.bzrignore index c4ae17ed95e..5e2aa892c28 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1064,3 +1064,5 @@ vio/test-ssl vio/test-sslclient vio/test-sslserver vio/viotest-ssl +include/check_abi +include/mysql_h.ic diff --git a/configure.in b/configure.in index 6cccb1bb90e..20dea3595de 100644 --- a/configure.in +++ b/configure.in @@ -508,6 +508,10 @@ AC_SUBST(DOXYGEN) AC_SUBST(PDFLATEX) AC_SUBST(MAKEINDEX) +# icheck, used for ABI check +AC_PATH_PROG(ICHECK, icheck, no) +AC_SUBST(ICHECK) + # Lock for PS AC_PATH_PROG(PS, ps, ps) AC_MSG_CHECKING("how to check if pid exists") diff --git a/include/Makefile.am b/include/Makefile.am index 3fa7b04d69a..dc30d40a352 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -15,7 +15,7 @@ # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, # MA 02111-1307, USA -BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h +BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h mysql_h.ic pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \ mysql.h mysql_com.h mysqld_error.h mysql_embed.h \ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \ @@ -32,8 +32,10 @@ noinst_HEADERS = config-win.h config-os2.h config-netware.h \ thr_lock.h t_ctype.h violite.h md5.h \ mysql_version.h.in my_handler.h my_time.h +CLEANFILES = mysql_h.ic + # mysql_version.h are generated -SUPERCLEANFILES = mysql_version.h my_config.h +SUPERCLEANFILES = mysql_version.h my_config.h $(CLEANFILES) # Some include files that may be moved and patched by configure DISTCLEANFILES = sched.h $(SUPERCLEANFILES) @@ -55,5 +57,27 @@ link_sources: dist-hook: $(RM) -f $(distdir)/mysql_version.h $(distdir)/my_config.h +# +# Rules for checking that ABI has not changed +# + +# Create a icheck file for mysql.h +mysql_h.ic: mysql.h + @set -x; \ + if [ @ICHECK@ != no ] ; then \ + @ICHECK@ --canonify -o $@ mysql.h; \ + fi; + +# Compare the icheck file to the reference +check_abi: mysql_h.ic + @set -x; \ + if [ @ICHECK@ != no ] ; then \ + @ICHECK@ --compare mysql_h.ic mysql_h_abi.ic; \ + fi; \ + touch check_abi; + +all: check_abi + + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/include/mysql.h b/include/mysql.h index 143f6752c46..bc99b6f6ba1 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -14,6 +14,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +/* + This file defines the client API to MySQL and also the ABI of the + dynamically linked libmysqlclient. + + The ABI should never be changed in a released product of MySQL + thus you need to take great care when changing the file. In case + the file is changed so the ABI is broken, you must also + update the SHAREDLIB_MAJOR_VERSION in configure.in . + +*/ + #ifndef _mysql_h #define _mysql_h diff --git a/include/mysql_h_abi.ic b/include/mysql_h_abi.ic new file mode 100644 index 00000000000..80d13199a8d --- /dev/null +++ b/include/mysql_h_abi.ic @@ -0,0 +1,1244 @@ +struct __pthread_internal_slist; +struct __pthread_mutex_s; +struct rand_struct; +struct st_list; +struct st_mem_root; +struct st_mysql; +struct st_mysql_bind; +struct st_mysql_data; +struct st_mysql_field; +struct st_mysql_manager; +struct st_mysql_methods; +struct st_mysql_options; +struct st_mysql_parameters; +struct st_mysql_res; +struct st_mysql_rows; +struct st_mysql_stmt; +struct st_mysql_time; +struct st_net; +struct st_typelib; +struct st_udf_args; +struct st_udf_init; +struct st_used_mem; +struct timespec; +struct timeval; +enum Item_result; +enum enum_field_types; +enum enum_mysql_set_option; +enum enum_mysql_stmt_state; +enum enum_mysql_timestamp_type; +enum enum_server_command; +enum enum_stmt_attr_type; +enum mysql_enum_shutdown_level; +enum mysql_option; +enum mysql_protocol_type; +enum mysql_rpl_type; +enum mysql_status; +# 59 "/usr/include/bits/types.h" +typedef long long int __quad_t; +# 135 "mysql.h" +typedef struct st_mysql_rows MYSQL_ROWS; +# 55 "/usr/include/sys/select.h" +typedef long int __fd_mask; +# 145 "/usr/include/bits/types.h" +typedef __quad_t __off64_t; +# 60 "/usr/include/bits/types.h" +typedef unsigned long long int __u_quad_t; +# 24 "my_list.h" +typedef struct st_list LIST; +# 236 "mysql.h" +typedef struct st_mysql MYSQL; +# 575 "mysql.h" +typedef struct st_mysql_bind MYSQL_BIND; +# 97 "mysql.h" +typedef struct st_mysql_field MYSQL_FIELD; +# 121 "mysql.h" +typedef unsigned int MYSQL_FIELD_OFFSET; +# 327 "mysql.h" +typedef struct st_mysql_manager MYSQL_MANAGER; +# 341 "mysql.h" +typedef struct st_mysql_parameters MYSQL_PARAMETERS; +# 296 "mysql.h" +typedef struct st_mysql_res MYSQL_RES; +# 120 "mysql.h" +typedef char * * MYSQL_ROW; +# 141 "mysql.h" +typedef MYSQL_ROWS * MYSQL_ROW_OFFSET; +# 600 "mysql.h" +typedef struct st_mysql_stmt MYSQL_STMT; +# 151 "mysql_com.h" +typedef struct st_net NET; +# 21 "typelib.h" +typedef struct st_typelib TYPELIB; +# 141 "mysql_com.h" +typedef struct st_vio Vio; +# 172 "/usr/include/bits/types.h" +typedef long int __blkcnt_t; +# 189 "/usr/include/bits/types.h" +typedef char * __caddr_t; +# 161 "/usr/include/bits/types.h" +typedef int __clockid_t; +# 156 "/usr/include/bits/types.h" +typedef int __daddr_t; +# 137 "/usr/include/bits/types.h" +typedef __u_quad_t __dev_t; +# 176 "/usr/include/bits/types.h" +typedef unsigned long int __fsblkcnt_t; +# 180 "/usr/include/bits/types.h" +typedef unsigned long int __fsfilcnt_t; +# 147 "/usr/include/bits/types.h" +typedef struct __attribute__((aligned(__alignof__(int)))) + { + int __val[2]; + } __fsid_t; +# 139 "/usr/include/bits/types.h" +typedef unsigned int __gid_t; +# 151 "/usr/include/bits/types.h" +typedef unsigned int __id_t; +# 140 "/usr/include/bits/types.h" +typedef unsigned long int __ino_t; +# 158 "/usr/include/bits/types.h" +typedef int __key_t; +# 187 "/usr/include/bits/types.h" +typedef __off64_t __loff_t; +# 142 "/usr/include/bits/types.h" +typedef unsigned int __mode_t; +# 143 "/usr/include/bits/types.h" +typedef unsigned int __nlink_t; +# 144 "/usr/include/bits/types.h" +typedef long int __off_t; +# 146 "/usr/include/bits/types.h" +typedef int __pid_t; +# 28 "/usr/include/bits/sigset.h" +typedef struct __attribute__((aligned(__alignof__(unsigned long int)))) + { + unsigned long int __val[(1024 / (8 * sizeof(unsigned long int)))]; + } __sigset_t; +# 183 "/usr/include/bits/types.h" +typedef int __ssize_t; +# 154 "/usr/include/bits/types.h" +typedef long int __suseconds_t; +# 152 "/usr/include/bits/types.h" +typedef long int __time_t; +# 164 "/usr/include/bits/types.h" +typedef void * __timer_t; +# 34 "/usr/include/bits/types.h" +typedef unsigned char __u_char; +# 36 "/usr/include/bits/types.h" +typedef unsigned int __u_int; +# 37 "/usr/include/bits/types.h" +typedef unsigned long int __u_long; +# 35 "/usr/include/bits/types.h" +typedef unsigned short int __u_short; +# 138 "/usr/include/bits/types.h" +typedef unsigned int __uid_t; +# 67 "/usr/include/sys/select.h" +typedef struct __attribute__((aligned(__alignof__(long int)))) + { + __fd_mask __fds_bits[(1024 / (8 * sizeof(__fd_mask)))]; + } fd_set; +# 61 "mysql.h" +typedef char * gptr; +# 29 "my_list.h" +typedef int (* list_walk_action)(void *, void *); +# 52 "mysql.h" +typedef char my_bool; +# 67 "mysql.h" +typedef int my_socket; +# 129 "mysql.h" +typedef unsigned long long int my_ulonglong; +# 35 "my_alloc.h" +typedef struct st_mem_root MEM_ROOT; +# 145 "mysql.h" +typedef struct st_mysql_data MYSQL_DATA; +# 652 "mysql.h" +typedef struct st_mysql_methods MYSQL_METHODS; +# 48 "mysql_time.h" +typedef struct st_mysql_time MYSQL_TIME; +# 315 "mysql_com.h" +typedef struct st_udf_args UDF_ARGS; +# 326 "mysql_com.h" +typedef struct st_udf_init UDF_INIT; +# 27 "my_alloc.h" +typedef struct st_used_mem USED_MEM; +# 173 "/usr/include/bits/types.h" +typedef __quad_t __blkcnt64_t; +# 167 "/usr/include/bits/types.h" +typedef long int __blksize_t; +# 148 "/usr/include/bits/types.h" +typedef long int __clock_t; +# 177 "/usr/include/bits/types.h" +typedef __u_quad_t __fsblkcnt64_t; +# 181 "/usr/include/bits/types.h" +typedef __u_quad_t __fsfilcnt64_t; +# 141 "/usr/include/bits/types.h" +typedef __u_quad_t __ino64_t; +# 42 "/usr/include/bits/types.h" +typedef short int __int16_t; +# 44 "/usr/include/bits/types.h" +typedef int __int32_t; +# 50 "/usr/include/bits/types.h" +typedef long long int __int64_t; +# 40 "/usr/include/bits/types.h" +typedef signed char __int8_t; +# 192 "/usr/include/bits/types.h" +typedef int __intptr_t; +# 46 "/usr/include/bits/pthreadtypes.h" +typedef struct __pthread_internal_slist __pthread_slist_t; +# 188 "/usr/include/bits/types.h" +typedef __quad_t * __qaddr_t; +# 150 "/usr/include/bits/types.h" +typedef __u_quad_t __rlim64_t; +# 149 "/usr/include/bits/types.h" +typedef unsigned long int __rlim_t; +# 23 "/usr/include/bits/sigset.h" +typedef int __sig_atomic_t; +# 195 "/usr/include/bits/types.h" +typedef unsigned int __socklen_t; +# 157 "/usr/include/bits/types.h" +typedef long int __swblk_t; +# 43 "/usr/include/bits/types.h" +typedef unsigned short int __uint16_t; +# 45 "/usr/include/bits/types.h" +typedef unsigned int __uint32_t; +# 51 "/usr/include/bits/types.h" +typedef unsigned long long int __uint64_t; +# 41 "/usr/include/bits/types.h" +typedef unsigned char __uint8_t; +# 153 "/usr/include/bits/types.h" +typedef unsigned int __useconds_t; +# 235 "/usr/include/sys/types.h" +typedef __blkcnt_t blkcnt_t; +# 117 "/usr/include/sys/types.h" +typedef __caddr_t caddr_t; +# 93 "/usr/include/time.h" +typedef __clockid_t clockid_t; +# 116 "/usr/include/sys/types.h" +typedef __daddr_t daddr_t; +# 62 "/usr/include/sys/types.h" +typedef __dev_t dev_t; +# 85 "/usr/include/sys/select.h" +typedef __fd_mask fd_mask; +# 239 "/usr/include/sys/types.h" +typedef __fsblkcnt_t fsblkcnt_t; +# 243 "/usr/include/sys/types.h" +typedef __fsfilcnt_t fsfilcnt_t; +# 41 "/usr/include/sys/types.h" +typedef __fsid_t fsid_t; +# 67 "/usr/include/sys/types.h" +typedef __gid_t gid_t; +# 105 "/usr/include/sys/types.h" +typedef __id_t id_t; +# 50 "/usr/include/sys/types.h" +typedef __ino_t ino_t; +# 196 "/usr/include/sys/types.h" +typedef int int16_t; +# 197 "/usr/include/sys/types.h" +typedef int int32_t; +# 198 "/usr/include/sys/types.h" +typedef int int64_t; +# 195 "/usr/include/sys/types.h" +typedef int int8_t; +# 123 "/usr/include/sys/types.h" +typedef __key_t key_t; +# 46 "/usr/include/sys/types.h" +typedef __loff_t loff_t; +# 72 "/usr/include/sys/types.h" +typedef __mode_t mode_t; +# 77 "/usr/include/sys/types.h" +typedef __nlink_t nlink_t; +# 88 "/usr/include/sys/types.h" +typedef __off_t off_t; +# 100 "/usr/include/sys/types.h" +typedef __pid_t pid_t; +# 39 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + char __size[36]; + long int __align; + } pthread_attr_t; +# 153 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + char __size[20]; + long int __align; + } pthread_barrier_t; +# 159 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(int)))) + { + char __size[4]; + int __align; + } pthread_barrierattr_t; +# 84 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) + { + struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) + { + int __lock; + unsigned int __futex; + unsigned long long int __total_seq; + unsigned long long int __wakeup_seq; + unsigned long long int __woken_seq; + void * __mutex; + unsigned int __nwaiters; + unsigned int __broadcast_seq; + } __data; + char __size[48]; + long long int __align; + } pthread_cond_t; +# 101 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + char __size[4]; + long int __align; + } pthread_condattr_t; +# 109 "/usr/include/bits/pthreadtypes.h" +typedef unsigned int pthread_key_t; +# 54 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + struct __pthread_mutex_s __data; + char __size[24]; + long int __align; + } pthread_mutex_t; +# 75 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + char __size[4]; + long int __align; + } pthread_mutexattr_t; +# 113 "/usr/include/bits/pthreadtypes.h" +typedef int pthread_once_t; +# 119 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + struct __attribute__((aligned(__alignof__(int)))) + { + int __lock; + unsigned int __nr_readers; + unsigned int __readers_wakeup; + unsigned int __writer_wakeup; + unsigned int __nr_readers_queued; + unsigned int __nr_writers_queued; + unsigned int __flags; + int __writer; + } __data; + char __size[32]; + long int __align; + } pthread_rwlock_t; +# 138 "/usr/include/bits/pthreadtypes.h" +typedef union __attribute__((aligned(__alignof__(long int)))) + { + char __size[8]; + long int __align; + } pthread_rwlockattr_t; +# 148 "/usr/include/bits/pthreadtypes.h" +typedef int volatile pthread_spinlock_t; +# 36 "/usr/include/bits/pthreadtypes.h" +typedef unsigned long int pthread_t; +# 39 "/usr/include/sys/types.h" +typedef __quad_t quad_t; +# 206 "/usr/include/sys/types.h" +typedef int register_t; +# 38 "/usr/include/sys/select.h" +typedef __sigset_t sigset_t; +# 214 "/usr/lib/gcc/i386-redhat-linux/4.0.2/include/stddef.h" +typedef unsigned int size_t; +# 110 "/usr/include/sys/types.h" +typedef __ssize_t ssize_t; +# 49 "/usr/include/sys/select.h" +typedef __suseconds_t suseconds_t; +# 77 "/usr/include/time.h" +typedef __time_t time_t; +# 105 "/usr/include/time.h" +typedef __timer_t timer_t; +# 35 "/usr/include/sys/types.h" +typedef __u_char u_char; +# 37 "/usr/include/sys/types.h" +typedef __u_int u_int; +# 202 "/usr/include/sys/types.h" +typedef unsigned int u_int16_t; +# 203 "/usr/include/sys/types.h" +typedef unsigned int u_int32_t; +# 204 "/usr/include/sys/types.h" +typedef unsigned int u_int64_t; +# 201 "/usr/include/sys/types.h" +typedef unsigned int u_int8_t; +# 38 "/usr/include/sys/types.h" +typedef __u_long u_long; +# 40 "/usr/include/sys/types.h" +typedef __u_quad_t u_quad_t; +# 36 "/usr/include/sys/types.h" +typedef __u_short u_short; +# 82 "/usr/include/sys/types.h" +typedef __uid_t uid_t; +# 153 "/usr/include/sys/types.h" +typedef unsigned int uint; +# 151 "/usr/include/sys/types.h" +typedef unsigned long int ulong; +# 152 "/usr/include/sys/types.h" +typedef unsigned short int ushort; +# 46 "/usr/include/bits/pthreadtypes.h" +struct __attribute__((aligned(__alignof__(void *)))) __pthread_internal_slist + { + struct __pthread_internal_slist * __next; + }; +# 54 "/usr/include/bits/pthreadtypes.h" +struct __attribute__((aligned(__alignof__(int)))) __pthread_mutex_s + { + int __lock; + unsigned int __count; + int __owner; + int __kind; + unsigned int __nusers; + }; +# 302 "mysql_com.h" +struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(double)))) rand_struct + { + unsigned long int seed1; + unsigned long int seed2; + unsigned long int max_value; + double max_value_dbl; + }; +# 24 "my_list.h" +struct __attribute__((aligned(__alignof__(void *)))) st_list + { + struct st_list * prev; + struct st_list * next; + void * data; + }; +# 35 "my_alloc.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int)))) st_mem_root + { + USED_MEM * free; + USED_MEM * used; + USED_MEM * pre_alloc; + unsigned int min_malloc; + unsigned int block_size; + unsigned int block_num; + unsigned int first_block_usage; + void (* error_handler)(void); + }; +# 236 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql + { + NET net; + gptr connector_fd; + char * host; + char * user; + char * passwd; + char * unix_socket; + char * server_version; + char * host_info; + char * info; + char * db; + struct charset_info_st * charset; + MYSQL_FIELD * fields; + MEM_ROOT field_alloc; + my_ulonglong affected_rows; + my_ulonglong insert_id; + my_ulonglong extra_info; + unsigned long int thread_id; + unsigned long int packet_length; + unsigned int port; + unsigned long int client_flag; + unsigned long int server_capabilities; + unsigned int protocol_version; + unsigned int field_count; + unsigned int server_status; + unsigned int server_language; + unsigned int warning_count; + struct st_mysql_options options; + enum mysql_status status; + my_bool free_me; + my_bool reconnect; + char scramble[(20 + 1)]; + my_bool rpl_pivot; + struct st_mysql * master; + struct st_mysql * next_slave; + struct st_mysql * last_used_slave; + struct st_mysql * last_used_con; + LIST * stmts; + struct st_mysql_methods const * methods; + void * thd; + my_bool * unbuffered_fetch_owner; + struct st_mysql_stmt * current_stmt; + }; +# 575 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind + { + unsigned long int * length; + my_bool * is_null; + void * buffer; + enum enum_field_types buffer_type; + unsigned long int buffer_length; + unsigned char * inter_buffer; + unsigned long int offset; + unsigned long int internal_length; + unsigned int param_number; + unsigned int pack_length; + my_bool is_unsigned; + my_bool long_data_used; + my_bool internal_is_null; + void (* store_param_func)(NET * net, struct st_mysql_bind * param); + void (* fetch_result)(struct st_mysql_bind *, unsigned char * * row); + void (* skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, unsigned char * * row); + }; +# 145 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_data + { + my_ulonglong rows; + unsigned int fields; + MYSQL_ROWS * data; + MEM_ROOT alloc; + MYSQL_ROWS * * prev_ptr; + }; +# 97 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_field + { + char * name; + char * org_name; + char * table; + char * org_table; + char * db; + char * catalog; + char * def; + unsigned long int length; + unsigned long int max_length; + unsigned int name_length; + unsigned int org_name_length; + unsigned int table_length; + unsigned int org_table_length; + unsigned int db_length; + unsigned int catalog_length; + unsigned int def_length; + unsigned int flags; + unsigned int decimals; + unsigned int charsetnr; + enum enum_field_types type; + }; +# 327 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_manager + { + NET net; + char * host; + char * user; + char * passwd; + unsigned int port; + my_bool free_me; + my_bool eof; + int cmd_status; + int last_errno; + char * net_buf; + char * net_buf_pos; + char * net_data_end; + int net_buf_size; + char last_error[256]; + }; +# 652 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)))) st_mysql_methods + { + my_bool (* read_query_result)(MYSQL * mysql); + my_bool (* advanced_command)(MYSQL * mysql, enum enum_server_command, char const * header, unsigned long int, char const * arg, unsigned long int, my_bool, MYSQL_STMT * stmt); + MYSQL_DATA * (* read_rows)(MYSQL * mysql, MYSQL_FIELD * mysql_fields, unsigned int); + MYSQL_RES * (* use_result)(MYSQL * mysql); + void (* fetch_lengths)(unsigned long int * to, MYSQL_ROW, unsigned int); + void (* flush_use_result)(MYSQL * mysql); + MYSQL_FIELD * (* list_fields)(MYSQL * mysql); + my_bool (* read_prepare_result)(MYSQL * mysql, MYSQL_STMT * stmt); + int (* stmt_execute)(MYSQL_STMT * stmt); + int (* read_binary_rows)(MYSQL_STMT * stmt); + int (* unbuffered_fetch)(MYSQL * mysql, char * * row); + void (* free_embedded_thd)(MYSQL * mysql); + char const * (* read_statistics)(MYSQL * mysql); + my_bool (* next_result)(MYSQL * mysql); + int (* read_change_user_result)(MYSQL * mysql, char * buff, char const * passwd); + }; +# 166 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_mysql_options + { + unsigned int connect_timeout; + unsigned int read_timeout; + unsigned int write_timeout; + unsigned int port; + unsigned int protocol; + unsigned long int client_flag; + char * host; + char * user; + char * password; + char * unix_socket; + char * db; + struct st_dynamic_array * init_commands; + char * my_cnf_file; + char * my_cnf_group; + char * charset_dir; + char * charset_name; + char * ssl_key; + char * ssl_cert; + char * ssl_ca; + char * ssl_capath; + char * ssl_cipher; + char * shared_memory_base_name; + unsigned long int max_allowed_packet; + my_bool use_ssl; + my_bool compress; + my_bool named_pipe; + my_bool rpl_probe; + my_bool rpl_parse; + my_bool no_master_reads; + my_bool separate_thread; + enum mysql_option methods_to_use; + char * client_ip; + my_bool secure_auth; + int (* local_infile_init)(void * *, char const *, void *); + int (* local_infile_read)(void *, char *, unsigned int); + void (* local_infile_end)(void); + int (* local_infile_error)(void *, char *, unsigned int); + void * local_infile_userdata; + }; +# 341 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)))) st_mysql_parameters + { + unsigned long int * p_max_allowed_packet; + unsigned long int * p_net_buffer_length; + }; +# 296 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_res + { + my_ulonglong row_count; + MYSQL_FIELD * fields; + MYSQL_DATA * data; + MYSQL_ROWS * data_cursor; + unsigned long int * lengths; + MYSQL * handle; + MEM_ROOT field_alloc; + unsigned int field_count; + unsigned int current_field; + MYSQL_ROW row; + MYSQL_ROW current_row; + my_bool eof; + my_bool unbuffered_fetch_cancelled; + struct st_mysql_methods const * methods; + }; +# 135 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_rows + { + struct st_mysql_rows * next; + MYSQL_ROW data; + unsigned long int length; + }; +# 600 "mysql.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql_stmt + { + MEM_ROOT mem_root; + LIST list; + MYSQL * mysql; + MYSQL_BIND * params; + MYSQL_BIND * bind; + MYSQL_FIELD * fields; + MYSQL_DATA result; + MYSQL_ROWS * data_cursor; + my_ulonglong affected_rows; + my_ulonglong insert_id; + int (* read_row_func)(struct st_mysql_stmt * stmt, unsigned char * * row); + unsigned long int stmt_id; + unsigned int last_errno; + unsigned int param_count; + unsigned int field_count; + enum enum_mysql_stmt_state state; + char last_error[512]; + char sqlstate[(5 + 1)]; + my_bool send_types_to_server; + my_bool bind_param_done; + my_bool bind_result_done; + my_bool unbuffered_fetch_cancelled; + my_bool update_max_length; + }; +# 48 "mysql_time.h" +struct __attribute__((aligned(__alignof__(unsigned long int)))) st_mysql_time + { + unsigned int year; + unsigned int month; + unsigned int day; + unsigned int hour; + unsigned int minute; + unsigned int second; + unsigned long int second_part; + my_bool neg; + enum enum_mysql_timestamp_type time_type; + }; +# 151 "mysql_com.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_net + { + Vio * vio; + unsigned char * buff; + unsigned char * buff_end; + unsigned char * write_pos; + unsigned char * read_pos; + my_socket fd; + unsigned long int max_packet; + unsigned long int max_packet_size; + unsigned int pkt_nr; + unsigned int compress_pkt_nr; + unsigned int write_timeout; + unsigned int read_timeout; + unsigned int retry_count; + int fcntl; + my_bool compress; + unsigned long int remain_in_buf; + unsigned long int length; + unsigned long int buf_length; + unsigned long int where_b; + unsigned int * return_status; + unsigned char reading_or_writing; + char save_char; + my_bool no_send_ok; + char last_error[512]; + char sqlstate[(5 + 1)]; + unsigned int last_errno; + unsigned char error; + gptr query_cache_query; + my_bool report_error; + my_bool return_errno; + }; +# 21 "typelib.h" +struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_typelib + { + unsigned int count; + char const * name; + char const * * type_names; + unsigned int * type_lengths; + }; +# 315 "mysql_com.h" +struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_udf_args + { + unsigned int arg_count; + enum Item_result * arg_type; + char * * args; + unsigned long int * lengths; + char * maybe_null; + }; +# 326 "mysql_com.h" +struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_udf_init + { + my_bool maybe_null; + unsigned int decimals; + unsigned long int max_length; + char * ptr; + my_bool const_item; + }; +# 27 "my_alloc.h" +struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int)))) st_used_mem + { + struct st_used_mem * next; + unsigned int left; + unsigned int size; + }; +# 121 "/usr/include/time.h" +struct __attribute__((aligned(__alignof__(long int)))) timespec + { + __time_t tv_sec; + long int tv_nsec; + }; +# 69 "/usr/include/bits/time.h" +struct __attribute__((aligned(__alignof__(long int)))) timeval + { + __time_t tv_sec; + __suseconds_t tv_usec; + }; +# 313 "mysql_com.h" +enum Item_result + { + STRING_RESULT = 0, + REAL_RESULT = 1, + INT_RESULT = 2, + ROW_RESULT = 3, + }; +# 186 "mysql_com.h" +enum enum_field_types + { + MYSQL_TYPE_DECIMAL = 0, + MYSQL_TYPE_TINY = 1, + MYSQL_TYPE_SHORT = 2, + MYSQL_TYPE_LONG = 3, + MYSQL_TYPE_FLOAT = 4, + MYSQL_TYPE_DOUBLE = 5, + MYSQL_TYPE_NULL = 6, + MYSQL_TYPE_TIMESTAMP = 7, + MYSQL_TYPE_LONGLONG = 8, + MYSQL_TYPE_INT24 = 9, + MYSQL_TYPE_DATE = 10, + MYSQL_TYPE_TIME = 11, + MYSQL_TYPE_DATETIME = 12, + MYSQL_TYPE_YEAR = 13, + MYSQL_TYPE_NEWDATE = 14, + MYSQL_TYPE_ENUM = 247, + MYSQL_TYPE_SET = 248, + MYSQL_TYPE_TINY_BLOB = 249, + MYSQL_TYPE_MEDIUM_BLOB = 250, + MYSQL_TYPE_LONG_BLOB = 251, + MYSQL_TYPE_BLOB = 252, + MYSQL_TYPE_VAR_STRING = 253, + MYSQL_TYPE_STRING = 254, + MYSQL_TYPE_GEOMETRY = 255, + }; +# 269 "mysql_com.h" +enum enum_mysql_set_option + { + MYSQL_OPTION_MULTI_STATEMENTS_ON = 0, + MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1, + }; +# 567 "mysql.h" +enum enum_mysql_stmt_state + { + MYSQL_STMT_INIT_DONE = 1, + MYSQL_STMT_PREPARE_DONE = 2, + MYSQL_STMT_EXECUTE_DONE = 3, + MYSQL_STMT_FETCH_DONE = 4, + }; +# 29 "mysql_time.h" +enum enum_mysql_timestamp_type + { + MYSQL_TIMESTAMP_NONE = -(2), + MYSQL_TIMESTAMP_ERROR = -(1), + MYSQL_TIMESTAMP_DATE = 0, + MYSQL_TIMESTAMP_DATETIME = 1, + MYSQL_TIMESTAMP_TIME = 2, + }; +# 39 "mysql_com.h" +enum enum_server_command + { + COM_SLEEP = 0, + COM_QUIT = 1, + COM_INIT_DB = 2, + COM_QUERY = 3, + COM_FIELD_LIST = 4, + COM_CREATE_DB = 5, + COM_DROP_DB = 6, + COM_REFRESH = 7, + COM_SHUTDOWN = 8, + COM_STATISTICS = 9, + COM_PROCESS_INFO = 10, + COM_CONNECT = 11, + COM_PROCESS_KILL = 12, + COM_DEBUG = 13, + COM_PING = 14, + COM_TIME = 15, + COM_DELAYED_INSERT = 16, + COM_CHANGE_USER = 17, + COM_BINLOG_DUMP = 18, + COM_TABLE_DUMP = 19, + COM_CONNECT_OUT = 20, + COM_REGISTER_SLAVE = 21, + COM_PREPARE = 22, + COM_EXECUTE = 23, + COM_LONG_DATA = 24, + COM_CLOSE_STMT = 25, + COM_RESET_STMT = 26, + COM_SET_OPTION = 27, + COM_END = 28, + }; +# 639 "mysql.h" +enum enum_stmt_attr_type + { + STMT_ATTR_UPDATE_MAX_LENGTH = 0, + }; +# 244 "mysql_com.h" +enum mysql_enum_shutdown_level + { + SHUTDOWN_DEFAULT = 0, + SHUTDOWN_WAIT_CONNECTIONS = (unsigned char)((1 << 0)), + SHUTDOWN_WAIT_TRANSACTIONS = (unsigned char)((1 << 1)), + SHUTDOWN_WAIT_UPDATES = (unsigned char)((1 << 3)), + SHUTDOWN_WAIT_ALL_BUFFERS = ((unsigned char)((1 << 3)) << 1), + SHUTDOWN_WAIT_CRITICAL_BUFFERS = (((unsigned char)((1 << 3)) << 1) + 1), + KILL_CONNECTION = 255, + }; +# 155 "mysql.h" +enum mysql_option + { + MYSQL_OPT_CONNECT_TIMEOUT = 0, + MYSQL_OPT_COMPRESS = 1, + MYSQL_OPT_NAMED_PIPE = 2, + MYSQL_INIT_COMMAND = 3, + MYSQL_READ_DEFAULT_FILE = 4, + MYSQL_READ_DEFAULT_GROUP = 5, + MYSQL_SET_CHARSET_DIR = 6, + MYSQL_SET_CHARSET_NAME = 7, + MYSQL_OPT_LOCAL_INFILE = 8, + MYSQL_OPT_PROTOCOL = 9, + MYSQL_SHARED_MEMORY_BASE_NAME = 10, + MYSQL_OPT_READ_TIMEOUT = 11, + MYSQL_OPT_WRITE_TIMEOUT = 12, + MYSQL_OPT_USE_RESULT = 13, + MYSQL_OPT_USE_REMOTE_CONNECTION = 14, + MYSQL_OPT_USE_EMBEDDED_CONNECTION = 15, + MYSQL_OPT_GUESS_CONNECTION = 16, + MYSQL_SET_CLIENT_IP = 17, + MYSQL_SECURE_AUTH = 18, + }; +# 218 "mysql.h" +enum mysql_protocol_type + { + MYSQL_PROTOCOL_DEFAULT = 0, + MYSQL_PROTOCOL_TCP = 1, + MYSQL_PROTOCOL_SOCKET = 2, + MYSQL_PROTOCOL_PIPE = 3, + MYSQL_PROTOCOL_MEMORY = 4, + }; +# 228 "mysql.h" +enum mysql_rpl_type + { + MYSQL_RPL_MASTER = 0, + MYSQL_RPL_SLAVE = 1, + MYSQL_RPL_ADMIN = 2, + }; +# 213 "mysql.h" +enum mysql_status + { + MYSQL_STATUS_READY = 0, + MYSQL_STATUS_GET_RESULT = 1, + MYSQL_STATUS_USE_RESULT = 2, + }; +# 365 "mysql_com.h" +extern my_bool check_scramble(char const * reply, char const * message, unsigned char const * hash_stage2); +# 358 "mysql_com.h" +extern my_bool check_scramble_323(char const *, char const * message, unsigned long int * salt); +# 353 "mysql_com.h" +extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st); +# 28 "typelib.h" +extern int find_type(char * x, TYPELIB * typelib, unsigned int); +# 367 "mysql_com.h" +extern void get_salt_from_password(unsigned char * res, char const * password); +# 360 "mysql_com.h" +extern void get_salt_from_password_323(unsigned long int * res, char const * password); +# 372 "mysql_com.h" +extern char * get_tty_password(char * opt_message); +# 30 "typelib.h" +extern char const * get_type(TYPELIB * typelib, unsigned int); +# 41 "/usr/include/sys/sysmacros.h" +extern unsigned int gnu_dev_major(unsigned long long int); +# 53 "/usr/include/sys/sysmacros.h" +extern unsigned long long int gnu_dev_makedev(unsigned int, unsigned int); +# 47 "/usr/include/sys/sysmacros.h" +extern unsigned int gnu_dev_minor(unsigned long long int); +# 355 "mysql_com.h" +extern void hash_password(unsigned long int * to, char const * password, unsigned int); +# 31 "my_list.h" +extern LIST * list_add(LIST * root, LIST * element); +# 33 "my_list.h" +extern LIST * list_cons(void * data, LIST * root); +# 32 "my_list.h" +extern LIST * list_delete(LIST * root, LIST * element); +# 35 "my_list.h" +extern void list_free(LIST * root, unsigned int); +# 36 "my_list.h" +extern unsigned int list_length(LIST *); +# 34 "my_list.h" +extern LIST * list_reverse(LIST * root); +# 37 "my_list.h" +extern int list_walk(LIST *, list_walk_action, gptr); +# 378 "mysql_com.h" +extern int load_defaults(char const * conf_file, char const * * groups, int * argc, char * * * argv); +# 368 "mysql_com.h" +extern void make_password_from_salt(char * to, unsigned char const * hash_stage2); +# 361 "mysql_com.h" +extern void make_password_from_salt_323(char * to, unsigned long int const * salt); +# 363 "mysql_com.h" +extern void make_scrambled_password(char * to, char const * password); +# 356 "mysql_com.h" +extern void make_scrambled_password_323(char * to, char const * password); +# 29 "typelib.h" +extern void make_type(char * to, unsigned int, TYPELIB * typelib); +# 299 "mysql_com.h" +extern int my_connect(my_socket, struct sockaddr const * name, unsigned int, unsigned int); +# 377 "mysql_com.h" +extern my_bool my_init(void); +# 281 "mysql_com.h" +extern my_bool my_net_init(NET * net, Vio * vio); +# 282 "mysql_com.h" +extern void my_net_local_init(NET * net); +# 292 "mysql_com.h" +extern unsigned long int my_net_read(NET * net); +# 287 "mysql_com.h" +extern my_bool my_net_write(NET * net, char const * packet, unsigned long int); +# 352 "mysql_com.h" +extern double my_rnd(struct rand_struct *); +# 381 "mysql_com.h" +extern void my_thread_end(void); +# 380 "mysql_com.h" +extern my_bool my_thread_init(void); +# 543 "mysql.h" +extern void myodbc_remove_escape(MYSQL * mysql, char * name); +# 485 "mysql.h" +extern int mysql_add_slave(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); +# 397 "mysql.h" +extern my_ulonglong mysql_affected_rows(MYSQL * mysql); +# 724 "mysql.h" +extern my_bool mysql_autocommit(MYSQL * mysql, my_bool); +# 412 "mysql.h" +extern my_bool mysql_change_user(MYSQL * mysql, char const * user, char const * passwd, char const * db); +# 405 "mysql.h" +extern char const * mysql_character_set_name(MYSQL * mysql); +# 727 "mysql.h" +extern void mysql_close(MYSQL * sock); +# 722 "mysql.h" +extern my_bool mysql_commit(MYSQL * mysql); +# 514 "mysql.h" +extern void mysql_data_seek(MYSQL_RES * result, my_ulonglong); +# 532 "mysql.h" +extern void mysql_debug(char const * debug); +# 471 "mysql.h" +extern void mysql_disable_reads_from_master(MYSQL * mysql); +# 465 "mysql.h" +extern void mysql_disable_rpl_parse(MYSQL * mysql); +# 493 "mysql.h" +extern int mysql_dump_debug_info(MYSQL * mysql); +# 545 "mysql.h" +extern my_bool mysql_embedded(void); +# 470 "mysql.h" +extern void mysql_enable_reads_from_master(MYSQL * mysql); +# 464 "mysql.h" +extern void mysql_enable_rpl_parse(MYSQL * mysql); +# 389 "mysql.h" +extern my_bool mysql_eof(MYSQL_RES * res); +# 399 "mysql.h" +extern unsigned int mysql_errno(MYSQL * mysql); +# 373 "mysql_com.h" +extern char const * mysql_errno_to_sqlstate(unsigned int); +# 400 "mysql.h" +extern char const * mysql_error(MYSQL * mysql); +# 525 "mysql.h" +extern unsigned long int mysql_escape_string(char * to, char const * from, unsigned long int); +# 522 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_field(MYSQL_RES * result); +# 390 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES * res, unsigned int); +# 392 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES * res); +# 521 "mysql.h" +extern unsigned long int * mysql_fetch_lengths(MYSQL_RES * result); +# 520 "mysql.h" +extern MYSQL_ROW mysql_fetch_row(MYSQL_RES * result); +# 396 "mysql.h" +extern unsigned int mysql_field_count(MYSQL * mysql); +# 518 "mysql.h" +extern MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES * result, MYSQL_FIELD_OFFSET); +# 394 "mysql.h" +extern MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES * res); +# 513 "mysql.h" +extern void mysql_free_result(MYSQL_RES * result); +# 503 "mysql.h" +extern char const * mysql_get_client_info(void); +# 504 "mysql.h" +extern unsigned long int mysql_get_client_version(void); +# 505 "mysql.h" +extern char const * mysql_get_host_info(MYSQL * mysql); +# 371 "mysql.h" +extern MYSQL_PARAMETERS * mysql_get_parameters(void); +# 507 "mysql.h" +extern unsigned int mysql_get_proto_info(MYSQL * mysql); +# 502 "mysql.h" +extern char const * mysql_get_server_info(MYSQL * mysql); +# 506 "mysql.h" +extern unsigned long int mysql_get_server_version(MYSQL * mysql); +# 527 "mysql.h" +extern unsigned long int mysql_hex_string(char * to, char const * from, unsigned long int); +# 403 "mysql.h" +extern char const * mysql_info(MYSQL * mysql); +# 408 "mysql.h" +extern MYSQL * mysql_init(MYSQL * mysql); +# 398 "mysql.h" +extern my_ulonglong mysql_insert_id(MYSQL * mysql); +# 496 "mysql.h" +extern int mysql_kill(MYSQL * mysql, unsigned long int); +# 508 "mysql.h" +extern MYSQL_RES * mysql_list_dbs(MYSQL * mysql, char const * wild); +# 523 "mysql.h" +extern MYSQL_RES * mysql_list_fields(MYSQL * mysql, char const * table, char const * wild); +# 510 "mysql.h" +extern MYSQL_RES * mysql_list_processes(MYSQL * mysql); +# 509 "mysql.h" +extern MYSQL_RES * mysql_list_tables(MYSQL * mysql, char const * wild); +# 552 "mysql.h" +extern void mysql_manager_close(MYSQL_MANAGER * con); +# 553 "mysql.h" +extern int mysql_manager_command(MYSQL_MANAGER * con, char const * cmd, int); +# 547 "mysql.h" +extern MYSQL_MANAGER * mysql_manager_connect(MYSQL_MANAGER * con, char const * host, char const * user, char const * passwd, unsigned int); +# 555 "mysql.h" +extern int mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int); +# 546 "mysql.h" +extern MYSQL_MANAGER * mysql_manager_init(MYSQL_MANAGER * con); +# 431 "mysql.h" +extern my_bool mysql_master_query(MYSQL * mysql, char const * q, unsigned long int); +# 433 "mysql.h" +extern my_bool mysql_master_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 725 "mysql.h" +extern my_bool mysql_more_results(MYSQL * mysql); +# 726 "mysql.h" +extern int mysql_next_result(MYSQL * mysql); +# 388 "mysql.h" +extern unsigned int mysql_num_fields(MYSQL_RES * res); +# 387 "mysql.h" +extern my_ulonglong mysql_num_rows(MYSQL_RES * res); +# 533 "mysql.h" +extern char * mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long int, char const * from, unsigned long int, void * param, char * (* extend_buffer)(void *, char * to, unsigned long int * length)); +# 511 "mysql.h" +extern int mysql_options(MYSQL * mysql, enum mysql_option, char const * arg); +# 500 "mysql.h" +extern int mysql_ping(MYSQL * mysql); +# 79 "mysql.h" +extern unsigned int mysql_port; +# 422 "mysql.h" +extern int mysql_query(MYSQL * mysql, char const * q); +# 558 "mysql.h" +extern my_bool mysql_read_query_result(MYSQL * mysql); +# 473 "mysql.h" +extern my_bool mysql_reads_from_master_enabled(MYSQL * mysql); +# 414 "mysql.h" +extern MYSQL * mysql_real_connect(MYSQL * mysql, char const * host, char const * user, char const * passwd, char const * db, unsigned int, char const * unix_socket, unsigned long int); +# 529 "mysql.h" +extern unsigned long int mysql_real_escape_string(MYSQL * mysql, char * to, char const * from, unsigned long int); +# 425 "mysql.h" +extern int mysql_real_query(MYSQL * mysql, char const * q, unsigned long int); +# 494 "mysql.h" +extern int mysql_refresh(MYSQL * mysql, unsigned int); +# 723 "mysql.h" +extern my_bool mysql_rollback(MYSQL * mysql); +# 516 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET); +# 393 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES * res); +# 467 "mysql.h" +extern int mysql_rpl_parse_enabled(MYSQL * mysql); +# 478 "mysql.h" +extern my_bool mysql_rpl_probe(MYSQL * mysql); +# 475 "mysql.h" +extern enum mysql_rpl_type mysql_rpl_query_type(char const * q, int); +# 421 "mysql.h" +extern int mysql_select_db(MYSQL * mysql, char const * db); +# 423 "mysql.h" +extern int mysql_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 358 "mysql.h" +extern void mysql_server_end(void); +# 357 "mysql.h" +extern int mysql_server_init(int, char * * argv, char * * groups); +# 406 "mysql.h" +extern int mysql_set_character_set(MYSQL * mysql, char const * csname); +# 456 "mysql.h" +extern void mysql_set_local_infile_default(MYSQL * mysql); +# 445 "mysql.h" +extern void mysql_set_local_infile_handler(MYSQL * mysql, int (* local_infile_init)(void * *, char const *, void *), int (* local_infile_read)(void *, char *, unsigned int), void (* local_infile_end)(void), int (* local_infile_error)(void *, char *, unsigned int), void *); +# 481 "mysql.h" +extern int mysql_set_master(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); +# 497 "mysql.h" +extern int mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option); +# 490 "mysql.h" +extern int mysql_shutdown(MYSQL * mysql, enum mysql_enum_shutdown_level); +# 436 "mysql.h" +extern my_bool mysql_slave_query(MYSQL * mysql, char const * q, unsigned long int); +# 438 "mysql.h" +extern my_bool mysql_slave_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 401 "mysql.h" +extern char const * mysql_sqlstate(MYSQL * mysql); +# 409 "mysql.h" +extern my_bool mysql_ssl_set(MYSQL * mysql, char const * key, char const * cert, char const * ca, char const * capath, char const * cipher); +# 501 "mysql.h" +extern char const * mysql_stat(MYSQL * mysql); +# 718 "mysql.h" +extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt); +# 696 "mysql.h" +extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr); +# 693 "mysql.h" +extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr); +# 699 "mysql.h" +extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 700 "mysql.h" +extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 701 "mysql.h" +extern my_bool mysql_stmt_close(MYSQL_STMT * stmt); +# 716 "mysql.h" +extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong); +# 710 "mysql.h" +extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt); +# 711 "mysql.h" +extern char const * mysql_stmt_error(MYSQL_STMT * stmt); +# 686 "mysql.h" +extern int mysql_stmt_execute(MYSQL_STMT * stmt); +# 687 "mysql.h" +extern int mysql_stmt_fetch(MYSQL_STMT * stmt); +# 688 "mysql.h" +extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind, unsigned int, unsigned long int); +# 720 "mysql.h" +extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt); +# 703 "mysql.h" +extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt); +# 683 "mysql.h" +extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql); +# 719 "mysql.h" +extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt); +# 717 "mysql.h" +extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt); +# 692 "mysql.h" +extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt); +# 709 "mysql.h" +extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt); +# 684 "mysql.h" +extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int); +# 702 "mysql.h" +extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt); +# 708 "mysql.h" +extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt); +# 713 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET); +# 715 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt); +# 704 "mysql.h" +extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int); +# 712 "mysql.h" +extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt); +# 691 "mysql.h" +extern int mysql_stmt_store_result(MYSQL_STMT * stmt); +# 427 "mysql.h" +extern MYSQL_RES * mysql_store_result(MYSQL * mysql); +# 380 "mysql.h" +extern void mysql_thread_end(void); +# 404 "mysql.h" +extern unsigned long int mysql_thread_id(MYSQL * mysql); +# 379 "mysql.h" +extern my_bool mysql_thread_init(void); +# 544 "mysql.h" +extern unsigned int mysql_thread_safe(void); +# 80 "mysql.h" +extern char * mysql_unix_port; +# 428 "mysql.h" +extern MYSQL_RES * mysql_use_result(MYSQL * mysql); +# 402 "mysql.h" +extern unsigned int mysql_warning_count(MYSQL * mysql); +# 284 "mysql_com.h" +extern void net_clear(NET * net); +# 283 "mysql_com.h" +extern void net_end(NET * net); +# 286 "mysql_com.h" +extern my_bool net_flush(NET * net); +# 291 "mysql_com.h" +extern int net_real_write(NET * net, char const * packet, unsigned long int); +# 285 "mysql_com.h" +extern my_bool net_realloc(NET * net, unsigned long int); +# 755 "mysql.h" +extern unsigned long int net_safe_read(MYSQL * mysql); +# 288 "mysql_com.h" +extern my_bool net_write_command(NET * net, unsigned char, char const * header, unsigned long int, char const * packet, unsigned long int); +# 121 "/usr/include/sys/select.h" +extern int pselect(int, fd_set * restrict __readfds, fd_set * restrict __writefds, fd_set * restrict __exceptfds, struct timespec const * restrict __timeout, __sigset_t const * restrict __sigmask); +# 350 "mysql_com.h" +extern void randominit(struct rand_struct *, unsigned long int, unsigned long int); +# 364 "mysql_com.h" +extern void scramble(char * to, char const * message, char const * password); +# 357 "mysql_com.h" +extern void scramble_323(char * to, char const * message, char const * password); +# 109 "/usr/include/sys/select.h" +extern int select(int, fd_set * restrict __readfds, fd_set * restrict __writefds, fd_set * restrict __exceptfds, struct timeval * restrict __timeout); +# 32 "typelib.h" +extern TYPELIB sql_protocol_typelib; From f89efeb5f60c8cdbf1a4f70003f7740623934220 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 21:02:04 +0200 Subject: [PATCH 204/235] Pass --core-file option to mysqld when bootstrapping BitKeeper/etc/ignore: Added mysql-test/r/blackhole.log to the ignore list --- .bzrignore | 1 + mysql-test/mysql-test-run.pl | 1 + 2 files changed, 2 insertions(+) diff --git a/.bzrignore b/.bzrignore index 5e2aa892c28..348093af390 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1066,3 +1066,4 @@ vio/test-sslserver vio/viotest-ssl include/check_abi include/mysql_h.ic +mysql-test/r/blackhole.log diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3046e5ba2fe..72b4fe95132 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2624,6 +2624,7 @@ sub install_db ($$) { mtr_add_arg($args, "--skip-innodb"); mtr_add_arg($args, "--skip-ndbcluster"); mtr_add_arg($args, "--tmpdir=."); + mtr_add_arg($args, "--core-file"); if ( $opt_debug ) { From 47b1c7f9a53c4b40cbaaae4da47e78a671bc5836 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 22:00:08 +0200 Subject: [PATCH 205/235] Update the reference file for mysql API/ABI for 5.0 include/mysql_h_abi.ic: Update the reference file for mysql API/ABI --- include/mysql_h_abi.ic | 720 ++++++++++++++++++++++------------------- 1 file changed, 386 insertions(+), 334 deletions(-) diff --git a/include/mysql_h_abi.ic b/include/mysql_h_abi.ic index 80d13199a8d..a0369b79b49 100644 --- a/include/mysql_h_abi.ic +++ b/include/mysql_h_abi.ic @@ -1,5 +1,6 @@ struct __pthread_internal_slist; struct __pthread_mutex_s; +struct character_set; struct rand_struct; struct st_list; struct st_mem_root; @@ -23,6 +24,7 @@ struct st_used_mem; struct timespec; struct timeval; enum Item_result; +enum enum_cursor_type; enum enum_field_types; enum enum_mysql_set_option; enum enum_mysql_stmt_state; @@ -36,7 +38,7 @@ enum mysql_rpl_type; enum mysql_status; # 59 "/usr/include/bits/types.h" typedef long long int __quad_t; -# 135 "mysql.h" +# 134 "mysql.h" typedef struct st_mysql_rows MYSQL_ROWS; # 55 "/usr/include/sys/select.h" typedef long int __fd_mask; @@ -46,31 +48,33 @@ typedef __quad_t __off64_t; typedef unsigned long long int __u_quad_t; # 24 "my_list.h" typedef struct st_list LIST; -# 236 "mysql.h" +# 251 "mysql.h" typedef struct st_mysql MYSQL; -# 575 "mysql.h" +# 653 "mysql.h" typedef struct st_mysql_bind MYSQL_BIND; -# 97 "mysql.h" +# 93 "mysql.h" typedef struct st_mysql_field MYSQL_FIELD; -# 121 "mysql.h" +# 117 "mysql.h" typedef unsigned int MYSQL_FIELD_OFFSET; -# 327 "mysql.h" +# 340 "mysql.h" typedef struct st_mysql_manager MYSQL_MANAGER; -# 341 "mysql.h" +# 354 "mysql.h" typedef struct st_mysql_parameters MYSQL_PARAMETERS; -# 296 "mysql.h" +# 309 "mysql.h" typedef struct st_mysql_res MYSQL_RES; -# 120 "mysql.h" +# 116 "mysql.h" typedef char * * MYSQL_ROW; -# 141 "mysql.h" +# 140 "mysql.h" typedef MYSQL_ROWS * MYSQL_ROW_OFFSET; -# 600 "mysql.h" +# 681 "mysql.h" typedef struct st_mysql_stmt MYSQL_STMT; -# 151 "mysql_com.h" +# 236 "mysql.h" +typedef struct character_set MY_CHARSET_INFO; +# 180 "mysql_com.h" typedef struct st_net NET; # 21 "typelib.h" typedef struct st_typelib TYPELIB; -# 141 "mysql_com.h" +# 170 "mysql_com.h" typedef struct st_vio Vio; # 172 "/usr/include/bits/types.h" typedef long int __blkcnt_t; @@ -137,27 +141,29 @@ typedef struct __attribute__((aligned(__alignof__(long int)))) { __fd_mask __fds_bits[(1024 / (8 * sizeof(__fd_mask)))]; } fd_set; -# 61 "mysql.h" +# 57 "mysql.h" typedef char * gptr; # 29 "my_list.h" typedef int (* list_walk_action)(void *, void *); -# 52 "mysql.h" +# 48 "mysql.h" typedef char my_bool; -# 67 "mysql.h" +# 63 "mysql.h" typedef int my_socket; -# 129 "mysql.h" +# 125 "mysql.h" typedef unsigned long long int my_ulonglong; +# 144 "mysql.h" +typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; # 35 "my_alloc.h" typedef struct st_mem_root MEM_ROOT; # 145 "mysql.h" typedef struct st_mysql_data MYSQL_DATA; -# 652 "mysql.h" +# 750 "mysql.h" typedef struct st_mysql_methods MYSQL_METHODS; # 48 "mysql_time.h" typedef struct st_mysql_time MYSQL_TIME; -# 315 "mysql_com.h" +# 371 "mysql_com.h" typedef struct st_udf_args UDF_ARGS; -# 326 "mysql_com.h" +# 384 "mysql_com.h" typedef struct st_udf_init UDF_INIT; # 27 "my_alloc.h" typedef struct st_used_mem USED_MEM; @@ -392,7 +398,19 @@ struct __attribute__((aligned(__alignof__(int)))) __pthread_mutex_s int __kind; unsigned int __nusers; }; -# 302 "mysql_com.h" +# 236 "mysql.h" +struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) character_set + { + unsigned int number; + unsigned int state; + char const * csname; + char const * name; + char const * comment; + char const * dir; + unsigned int mbminlen; + unsigned int mbmaxlen; + }; +# 357 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(double)))) rand_struct { unsigned long int seed1; @@ -419,7 +437,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned unsigned int first_block_usage; void (* error_handler)(void); }; -# 236 "mysql.h" +# 251 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql { NET net; @@ -462,26 +480,27 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned struct st_mysql_methods const * methods; void * thd; my_bool * unbuffered_fetch_owner; - struct st_mysql_stmt * current_stmt; }; -# 575 "mysql.h" +# 653 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind { unsigned long int * length; my_bool * is_null; void * buffer; + my_bool * error; enum enum_field_types buffer_type; unsigned long int buffer_length; - unsigned char * inter_buffer; + unsigned char * row_ptr; unsigned long int offset; - unsigned long int internal_length; + unsigned long int length_value; unsigned int param_number; unsigned int pack_length; + my_bool error_value; my_bool is_unsigned; my_bool long_data_used; - my_bool internal_is_null; + my_bool is_null_value; void (* store_param_func)(NET * net, struct st_mysql_bind * param); - void (* fetch_result)(struct st_mysql_bind *, unsigned char * * row); + void (* fetch_result)(struct st_mysql_bind *, MYSQL_FIELD *, unsigned char * * row); void (* skip_result)(struct st_mysql_bind *, MYSQL_FIELD *, unsigned char * * row); }; # 145 "mysql.h" @@ -491,9 +510,9 @@ struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__al unsigned int fields; MYSQL_ROWS * data; MEM_ROOT alloc; - MYSQL_ROWS * * prev_ptr; + struct embedded_query_result * embedded_info; }; -# 97 "mysql.h" +# 93 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_field { char * name; @@ -517,7 +536,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned unsigned int charsetnr; enum enum_field_types type; }; -# 327 "mysql.h" +# 340 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_manager { NET net; @@ -535,7 +554,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned int net_buf_size; char last_error[256]; }; -# 652 "mysql.h" +# 750 "mysql.h" struct __attribute__((aligned(__alignof__(void *)))) st_mysql_methods { my_bool (* read_query_result)(MYSQL * mysql); @@ -553,8 +572,9 @@ struct __attribute__((aligned(__alignof__(void *)))) st_mysql_methods char const * (* read_statistics)(MYSQL * mysql); my_bool (* next_result)(MYSQL * mysql); int (* read_change_user_result)(MYSQL * mysql, char * buff, char const * passwd); + int (* read_rows_from_cursor)(MYSQL_STMT * stmt); }; -# 166 "mysql.h" +# 167 "mysql.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_mysql_options { unsigned int connect_timeout; @@ -590,19 +610,20 @@ struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof enum mysql_option methods_to_use; char * client_ip; my_bool secure_auth; + my_bool report_data_truncation; int (* local_infile_init)(void * *, char const *, void *); int (* local_infile_read)(void *, char *, unsigned int); void (* local_infile_end)(void); int (* local_infile_error)(void *, char *, unsigned int); void * local_infile_userdata; }; -# 341 "mysql.h" +# 354 "mysql.h" struct __attribute__((aligned(__alignof__(void *)))) st_mysql_parameters { unsigned long int * p_max_allowed_packet; unsigned long int * p_net_buffer_length; }; -# 296 "mysql.h" +# 309 "mysql.h" struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) st_mysql_res { my_ulonglong row_count; @@ -620,14 +641,14 @@ struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__al my_bool unbuffered_fetch_cancelled; struct st_mysql_methods const * methods; }; -# 135 "mysql.h" +# 134 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_rows { struct st_mysql_rows * next; MYSQL_ROW data; unsigned long int length; }; -# 600 "mysql.h" +# 681 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql_stmt { MEM_ROOT mem_root; @@ -642,6 +663,9 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned my_ulonglong insert_id; int (* read_row_func)(struct st_mysql_stmt * stmt, unsigned char * * row); unsigned long int stmt_id; + unsigned long int flags; + unsigned long int prefetch_rows; + unsigned int server_status; unsigned int last_errno; unsigned int param_count; unsigned int field_count; @@ -650,7 +674,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned char sqlstate[(5 + 1)]; my_bool send_types_to_server; my_bool bind_param_done; - my_bool bind_result_done; + unsigned char bind_result_done; my_bool unbuffered_fetch_cancelled; my_bool update_max_length; }; @@ -667,7 +691,7 @@ struct __attribute__((aligned(__alignof__(unsigned long int)))) st_mysql_time my_bool neg; enum enum_mysql_timestamp_type time_type; }; -# 151 "mysql_com.h" +# 180 "mysql_com.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_net { Vio * vio; @@ -693,6 +717,8 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned unsigned char reading_or_writing; char save_char; my_bool no_send_ok; + my_bool no_send_eof; + my_bool no_send_error; char last_error[512]; char sqlstate[(5 + 1)]; unsigned int last_errno; @@ -709,7 +735,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo char const * * type_names; unsigned int * type_lengths; }; -# 315 "mysql_com.h" +# 371 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_udf_args { unsigned int arg_count; @@ -717,8 +743,10 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo char * * args; unsigned long int * lengths; char * maybe_null; + char * * attributes; + unsigned long int * attribute_lengths; }; -# 326 "mysql_com.h" +# 384 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_udf_init { my_bool maybe_null; @@ -746,15 +774,24 @@ struct __attribute__((aligned(__alignof__(long int)))) timeval __time_t tv_sec; __suseconds_t tv_usec; }; -# 313 "mysql_com.h" +# 368 "mysql_com.h" enum Item_result { STRING_RESULT = 0, REAL_RESULT = 1, INT_RESULT = 2, ROW_RESULT = 3, + DECIMAL_RESULT = 4, }; -# 186 "mysql_com.h" +# 314 "mysql_com.h" +enum enum_cursor_type + { + CURSOR_TYPE_NO_CURSOR = 0, + CURSOR_TYPE_READ_ONLY = 1, + CURSOR_TYPE_FOR_UPDATE = 2, + CURSOR_TYPE_SCROLLABLE = 4, + }; +# 227 "mysql_com.h" enum enum_field_types { MYSQL_TYPE_DECIMAL = 0, @@ -772,6 +809,9 @@ enum enum_field_types MYSQL_TYPE_DATETIME = 12, MYSQL_TYPE_YEAR = 13, MYSQL_TYPE_NEWDATE = 14, + MYSQL_TYPE_VARCHAR = 15, + MYSQL_TYPE_BIT = 16, + MYSQL_TYPE_NEWDECIMAL = 246, MYSQL_TYPE_ENUM = 247, MYSQL_TYPE_SET = 248, MYSQL_TYPE_TINY_BLOB = 249, @@ -782,13 +822,13 @@ enum enum_field_types MYSQL_TYPE_STRING = 254, MYSQL_TYPE_GEOMETRY = 255, }; -# 269 "mysql_com.h" +# 324 "mysql_com.h" enum enum_mysql_set_option { MYSQL_OPTION_MULTI_STATEMENTS_ON = 0, MYSQL_OPTION_MULTI_STATEMENTS_OFF = 1, }; -# 567 "mysql.h" +# 583 "mysql.h" enum enum_mysql_stmt_state { MYSQL_STMT_INIT_DONE = 1, @@ -805,7 +845,7 @@ enum enum_mysql_timestamp_type MYSQL_TIMESTAMP_DATETIME = 1, MYSQL_TIMESTAMP_TIME = 2, }; -# 39 "mysql_com.h" +# 52 "mysql_com.h" enum enum_server_command { COM_SLEEP = 0, @@ -830,20 +870,23 @@ enum enum_server_command COM_TABLE_DUMP = 19, COM_CONNECT_OUT = 20, COM_REGISTER_SLAVE = 21, - COM_PREPARE = 22, - COM_EXECUTE = 23, - COM_LONG_DATA = 24, - COM_CLOSE_STMT = 25, - COM_RESET_STMT = 26, + COM_STMT_PREPARE = 22, + COM_STMT_EXECUTE = 23, + COM_STMT_SEND_LONG_DATA = 24, + COM_STMT_CLOSE = 25, + COM_STMT_RESET = 26, COM_SET_OPTION = 27, - COM_END = 28, + COM_STMT_FETCH = 28, + COM_END = 29, }; -# 639 "mysql.h" +# 727 "mysql.h" enum enum_stmt_attr_type { STMT_ATTR_UPDATE_MAX_LENGTH = 0, + STMT_ATTR_CURSOR_TYPE = 1, + STMT_ATTR_PREFETCH_ROWS = 2, }; -# 244 "mysql_com.h" +# 289 "mysql_com.h" enum mysql_enum_shutdown_level { SHUTDOWN_DEFAULT = 0, @@ -854,7 +897,7 @@ enum mysql_enum_shutdown_level SHUTDOWN_WAIT_CRITICAL_BUFFERS = (((unsigned char)((1 << 3)) << 1) + 1), KILL_CONNECTION = 255, }; -# 155 "mysql.h" +# 154 "mysql.h" enum mysql_option { MYSQL_OPT_CONNECT_TIMEOUT = 0, @@ -876,8 +919,11 @@ enum mysql_option MYSQL_OPT_GUESS_CONNECTION = 16, MYSQL_SET_CLIENT_IP = 17, MYSQL_SECURE_AUTH = 18, + MYSQL_REPORT_DATA_TRUNCATION = 19, + MYSQL_OPT_RECONNECT = 20, + MYSQL_OPT_SSL_VERIFY_SERVER_CERT = 21, }; -# 218 "mysql.h" +# 221 "mysql.h" enum mysql_protocol_type { MYSQL_PROTOCOL_DEFAULT = 0, @@ -886,33 +932,33 @@ enum mysql_protocol_type MYSQL_PROTOCOL_PIPE = 3, MYSQL_PROTOCOL_MEMORY = 4, }; -# 228 "mysql.h" +# 231 "mysql.h" enum mysql_rpl_type { MYSQL_RPL_MASTER = 0, MYSQL_RPL_SLAVE = 1, MYSQL_RPL_ADMIN = 2, }; -# 213 "mysql.h" +# 216 "mysql.h" enum mysql_status { MYSQL_STATUS_READY = 0, MYSQL_STATUS_GET_RESULT = 1, MYSQL_STATUS_USE_RESULT = 2, }; -# 365 "mysql_com.h" +# 423 "mysql_com.h" extern my_bool check_scramble(char const * reply, char const * message, unsigned char const * hash_stage2); -# 358 "mysql_com.h" +# 416 "mysql_com.h" extern my_bool check_scramble_323(char const *, char const * message, unsigned long int * salt); -# 353 "mysql_com.h" +# 411 "mysql_com.h" extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st); # 28 "typelib.h" extern int find_type(char * x, TYPELIB * typelib, unsigned int); -# 367 "mysql_com.h" +# 425 "mysql_com.h" extern void get_salt_from_password(unsigned char * res, char const * password); -# 360 "mysql_com.h" +# 418 "mysql_com.h" extern void get_salt_from_password_323(unsigned long int * res, char const * password); -# 372 "mysql_com.h" +# 431 "mysql_com.h" extern char * get_tty_password(char * opt_message); # 30 "typelib.h" extern char const * get_type(TYPELIB * typelib, unsigned int); @@ -922,7 +968,7 @@ extern unsigned int gnu_dev_major(unsigned long long int); extern unsigned long long int gnu_dev_makedev(unsigned int, unsigned int); # 47 "/usr/include/sys/sysmacros.h" extern unsigned int gnu_dev_minor(unsigned long long int); -# 355 "mysql_com.h" +# 413 "mysql_com.h" extern void hash_password(unsigned long int * to, char const * password, unsigned int); # 31 "my_list.h" extern LIST * list_add(LIST * root, LIST * element); @@ -938,305 +984,311 @@ extern unsigned int list_length(LIST *); extern LIST * list_reverse(LIST * root); # 37 "my_list.h" extern int list_walk(LIST *, list_walk_action, gptr); -# 378 "mysql_com.h" +# 440 "mysql_com.h" extern int load_defaults(char const * conf_file, char const * * groups, int * argc, char * * * argv); -# 368 "mysql_com.h" +# 426 "mysql_com.h" extern void make_password_from_salt(char * to, unsigned char const * hash_stage2); -# 361 "mysql_com.h" +# 419 "mysql_com.h" extern void make_password_from_salt_323(char * to, unsigned long int const * salt); -# 363 "mysql_com.h" +# 421 "mysql_com.h" extern void make_scrambled_password(char * to, char const * password); -# 356 "mysql_com.h" +# 414 "mysql_com.h" extern void make_scrambled_password_323(char * to, char const * password); # 29 "typelib.h" extern void make_type(char * to, unsigned int, TYPELIB * typelib); -# 299 "mysql_com.h" +# 437 "mysql_com.h" +extern int modify_defaults_file(char const * file_location, char const * option, char const * option_value, char const * section_name, int); +# 354 "mysql_com.h" extern int my_connect(my_socket, struct sockaddr const * name, unsigned int, unsigned int); -# 377 "mysql_com.h" +# 436 "mysql_com.h" extern my_bool my_init(void); -# 281 "mysql_com.h" +# 336 "mysql_com.h" extern my_bool my_net_init(NET * net, Vio * vio); -# 282 "mysql_com.h" +# 337 "mysql_com.h" extern void my_net_local_init(NET * net); -# 292 "mysql_com.h" +# 347 "mysql_com.h" extern unsigned long int my_net_read(NET * net); -# 287 "mysql_com.h" +# 342 "mysql_com.h" extern my_bool my_net_write(NET * net, char const * packet, unsigned long int); -# 352 "mysql_com.h" +# 410 "mysql_com.h" extern double my_rnd(struct rand_struct *); -# 381 "mysql_com.h" +# 443 "mysql_com.h" extern void my_thread_end(void); -# 380 "mysql_com.h" +# 442 "mysql_com.h" extern my_bool my_thread_init(void); -# 543 "mysql.h" +# 559 "mysql.h" extern void myodbc_remove_escape(MYSQL * mysql, char * name); -# 485 "mysql.h" -extern int mysql_add_slave(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); -# 397 "mysql.h" -extern my_ulonglong mysql_affected_rows(MYSQL * mysql); -# 724 "mysql.h" -extern my_bool mysql_autocommit(MYSQL * mysql, my_bool); -# 412 "mysql.h" -extern my_bool mysql_change_user(MYSQL * mysql, char const * user, char const * passwd, char const * db); -# 405 "mysql.h" -extern char const * mysql_character_set_name(MYSQL * mysql); -# 727 "mysql.h" -extern void mysql_close(MYSQL * sock); -# 722 "mysql.h" -extern my_bool mysql_commit(MYSQL * mysql); -# 514 "mysql.h" -extern void mysql_data_seek(MYSQL_RES * result, my_ulonglong); -# 532 "mysql.h" -extern void mysql_debug(char const * debug); -# 471 "mysql.h" -extern void mysql_disable_reads_from_master(MYSQL * mysql); -# 465 "mysql.h" -extern void mysql_disable_rpl_parse(MYSQL * mysql); -# 493 "mysql.h" -extern int mysql_dump_debug_info(MYSQL * mysql); -# 545 "mysql.h" -extern my_bool mysql_embedded(void); -# 470 "mysql.h" -extern void mysql_enable_reads_from_master(MYSQL * mysql); -# 464 "mysql.h" -extern void mysql_enable_rpl_parse(MYSQL * mysql); -# 389 "mysql.h" -extern my_bool mysql_eof(MYSQL_RES * res); -# 399 "mysql.h" -extern unsigned int mysql_errno(MYSQL * mysql); -# 373 "mysql_com.h" -extern char const * mysql_errno_to_sqlstate(unsigned int); -# 400 "mysql.h" -extern char const * mysql_error(MYSQL * mysql); -# 525 "mysql.h" -extern unsigned long int mysql_escape_string(char * to, char const * from, unsigned long int); -# 522 "mysql.h" -extern MYSQL_FIELD * mysql_fetch_field(MYSQL_RES * result); -# 390 "mysql.h" -extern MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES * res, unsigned int); -# 392 "mysql.h" -extern MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES * res); -# 521 "mysql.h" -extern unsigned long int * mysql_fetch_lengths(MYSQL_RES * result); -# 520 "mysql.h" -extern MYSQL_ROW mysql_fetch_row(MYSQL_RES * result); -# 396 "mysql.h" -extern unsigned int mysql_field_count(MYSQL * mysql); -# 518 "mysql.h" -extern MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES * result, MYSQL_FIELD_OFFSET); -# 394 "mysql.h" -extern MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES * res); -# 513 "mysql.h" -extern void mysql_free_result(MYSQL_RES * result); -# 503 "mysql.h" -extern char const * mysql_get_client_info(void); -# 504 "mysql.h" -extern unsigned long int mysql_get_client_version(void); -# 505 "mysql.h" -extern char const * mysql_get_host_info(MYSQL * mysql); -# 371 "mysql.h" -extern MYSQL_PARAMETERS * mysql_get_parameters(void); -# 507 "mysql.h" -extern unsigned int mysql_get_proto_info(MYSQL * mysql); -# 502 "mysql.h" -extern char const * mysql_get_server_info(MYSQL * mysql); -# 506 "mysql.h" -extern unsigned long int mysql_get_server_version(MYSQL * mysql); -# 527 "mysql.h" -extern unsigned long int mysql_hex_string(char * to, char const * from, unsigned long int); -# 403 "mysql.h" -extern char const * mysql_info(MYSQL * mysql); -# 408 "mysql.h" -extern MYSQL * mysql_init(MYSQL * mysql); -# 398 "mysql.h" -extern my_ulonglong mysql_insert_id(MYSQL * mysql); -# 496 "mysql.h" -extern int mysql_kill(MYSQL * mysql, unsigned long int); -# 508 "mysql.h" -extern MYSQL_RES * mysql_list_dbs(MYSQL * mysql, char const * wild); -# 523 "mysql.h" -extern MYSQL_RES * mysql_list_fields(MYSQL * mysql, char const * table, char const * wild); -# 510 "mysql.h" -extern MYSQL_RES * mysql_list_processes(MYSQL * mysql); -# 509 "mysql.h" -extern MYSQL_RES * mysql_list_tables(MYSQL * mysql, char const * wild); -# 552 "mysql.h" -extern void mysql_manager_close(MYSQL_MANAGER * con); -# 553 "mysql.h" -extern int mysql_manager_command(MYSQL_MANAGER * con, char const * cmd, int); -# 547 "mysql.h" -extern MYSQL_MANAGER * mysql_manager_connect(MYSQL_MANAGER * con, char const * host, char const * user, char const * passwd, unsigned int); -# 555 "mysql.h" -extern int mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int); -# 546 "mysql.h" -extern MYSQL_MANAGER * mysql_manager_init(MYSQL_MANAGER * con); -# 431 "mysql.h" -extern my_bool mysql_master_query(MYSQL * mysql, char const * q, unsigned long int); -# 433 "mysql.h" -extern my_bool mysql_master_send_query(MYSQL * mysql, char const * q, unsigned long int); -# 725 "mysql.h" -extern my_bool mysql_more_results(MYSQL * mysql); -# 726 "mysql.h" -extern int mysql_next_result(MYSQL * mysql); -# 388 "mysql.h" -extern unsigned int mysql_num_fields(MYSQL_RES * res); -# 387 "mysql.h" -extern my_ulonglong mysql_num_rows(MYSQL_RES * res); -# 533 "mysql.h" -extern char * mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long int, char const * from, unsigned long int, void * param, char * (* extend_buffer)(void *, char * to, unsigned long int * length)); -# 511 "mysql.h" -extern int mysql_options(MYSQL * mysql, enum mysql_option, char const * arg); -# 500 "mysql.h" -extern int mysql_ping(MYSQL * mysql); -# 79 "mysql.h" -extern unsigned int mysql_port; -# 422 "mysql.h" -extern int mysql_query(MYSQL * mysql, char const * q); -# 558 "mysql.h" -extern my_bool mysql_read_query_result(MYSQL * mysql); -# 473 "mysql.h" -extern my_bool mysql_reads_from_master_enabled(MYSQL * mysql); -# 414 "mysql.h" -extern MYSQL * mysql_real_connect(MYSQL * mysql, char const * host, char const * user, char const * passwd, char const * db, unsigned int, char const * unix_socket, unsigned long int); -# 529 "mysql.h" -extern unsigned long int mysql_real_escape_string(MYSQL * mysql, char * to, char const * from, unsigned long int); -# 425 "mysql.h" -extern int mysql_real_query(MYSQL * mysql, char const * q, unsigned long int); -# 494 "mysql.h" -extern int mysql_refresh(MYSQL * mysql, unsigned int); -# 723 "mysql.h" -extern my_bool mysql_rollback(MYSQL * mysql); -# 516 "mysql.h" -extern MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET); -# 393 "mysql.h" -extern MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES * res); -# 467 "mysql.h" -extern int mysql_rpl_parse_enabled(MYSQL * mysql); -# 478 "mysql.h" -extern my_bool mysql_rpl_probe(MYSQL * mysql); -# 475 "mysql.h" -extern enum mysql_rpl_type mysql_rpl_query_type(char const * q, int); -# 421 "mysql.h" -extern int mysql_select_db(MYSQL * mysql, char const * db); -# 423 "mysql.h" -extern int mysql_send_query(MYSQL * mysql, char const * q, unsigned long int); -# 358 "mysql.h" -extern void mysql_server_end(void); -# 357 "mysql.h" -extern int mysql_server_init(int, char * * argv, char * * groups); -# 406 "mysql.h" -extern int mysql_set_character_set(MYSQL * mysql, char const * csname); -# 456 "mysql.h" -extern void mysql_set_local_infile_default(MYSQL * mysql); -# 445 "mysql.h" -extern void mysql_set_local_infile_handler(MYSQL * mysql, int (* local_infile_init)(void * *, char const *, void *), int (* local_infile_read)(void *, char *, unsigned int), void (* local_infile_end)(void), int (* local_infile_error)(void *, char *, unsigned int), void *); -# 481 "mysql.h" -extern int mysql_set_master(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); -# 497 "mysql.h" -extern int mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option); -# 490 "mysql.h" -extern int mysql_shutdown(MYSQL * mysql, enum mysql_enum_shutdown_level); -# 436 "mysql.h" -extern my_bool mysql_slave_query(MYSQL * mysql, char const * q, unsigned long int); -# 438 "mysql.h" -extern my_bool mysql_slave_send_query(MYSQL * mysql, char const * q, unsigned long int); -# 401 "mysql.h" -extern char const * mysql_sqlstate(MYSQL * mysql); -# 409 "mysql.h" -extern my_bool mysql_ssl_set(MYSQL * mysql, char const * key, char const * cert, char const * ca, char const * capath, char const * cipher); # 501 "mysql.h" -extern char const * mysql_stat(MYSQL * mysql); -# 718 "mysql.h" -extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt); -# 696 "mysql.h" -extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr); -# 693 "mysql.h" -extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr); -# 699 "mysql.h" -extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); -# 700 "mysql.h" -extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); -# 701 "mysql.h" -extern my_bool mysql_stmt_close(MYSQL_STMT * stmt); -# 716 "mysql.h" -extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong); -# 710 "mysql.h" -extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt); -# 711 "mysql.h" -extern char const * mysql_stmt_error(MYSQL_STMT * stmt); -# 686 "mysql.h" -extern int mysql_stmt_execute(MYSQL_STMT * stmt); -# 687 "mysql.h" -extern int mysql_stmt_fetch(MYSQL_STMT * stmt); -# 688 "mysql.h" -extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind, unsigned int, unsigned long int); -# 720 "mysql.h" -extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt); -# 703 "mysql.h" -extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt); -# 683 "mysql.h" -extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql); -# 719 "mysql.h" -extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt); -# 717 "mysql.h" -extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt); -# 692 "mysql.h" -extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt); -# 709 "mysql.h" -extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt); -# 684 "mysql.h" -extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int); -# 702 "mysql.h" -extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt); -# 708 "mysql.h" -extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt); -# 713 "mysql.h" -extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET); -# 715 "mysql.h" -extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt); -# 704 "mysql.h" -extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int); -# 712 "mysql.h" -extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt); -# 691 "mysql.h" -extern int mysql_stmt_store_result(MYSQL_STMT * stmt); -# 427 "mysql.h" -extern MYSQL_RES * mysql_store_result(MYSQL * mysql); -# 380 "mysql.h" -extern void mysql_thread_end(void); -# 404 "mysql.h" -extern unsigned long int mysql_thread_id(MYSQL * mysql); -# 379 "mysql.h" -extern my_bool mysql_thread_init(void); -# 544 "mysql.h" -extern unsigned int mysql_thread_safe(void); -# 80 "mysql.h" -extern char * mysql_unix_port; -# 428 "mysql.h" -extern MYSQL_RES * mysql_use_result(MYSQL * mysql); +extern int mysql_add_slave(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); +# 410 "mysql.h" +extern my_ulonglong mysql_affected_rows(MYSQL * mysql); +# 823 "mysql.h" +extern my_bool mysql_autocommit(MYSQL * mysql, my_bool); +# 426 "mysql.h" +extern my_bool mysql_change_user(MYSQL * mysql, char const * user, char const * passwd, char const * db); +# 418 "mysql.h" +extern char const * mysql_character_set_name(MYSQL * mysql); +# 826 "mysql.h" +extern void mysql_close(MYSQL * sock); +# 821 "mysql.h" +extern my_bool mysql_commit(MYSQL * mysql); +# 530 "mysql.h" +extern void mysql_data_seek(MYSQL_RES * result, my_ulonglong); +# 548 "mysql.h" +extern void mysql_debug(char const * debug); +# 487 "mysql.h" +extern void mysql_disable_reads_from_master(MYSQL * mysql); +# 481 "mysql.h" +extern void mysql_disable_rpl_parse(MYSQL * mysql); +# 509 "mysql.h" +extern int mysql_dump_debug_info(MYSQL * mysql); +# 561 "mysql.h" +extern my_bool mysql_embedded(void); +# 486 "mysql.h" +extern void mysql_enable_reads_from_master(MYSQL * mysql); +# 480 "mysql.h" +extern void mysql_enable_rpl_parse(MYSQL * mysql); # 402 "mysql.h" +extern my_bool mysql_eof(MYSQL_RES * res); +# 412 "mysql.h" +extern unsigned int mysql_errno(MYSQL * mysql); +# 432 "mysql_com.h" +extern char const * mysql_errno_to_sqlstate(unsigned int); +# 413 "mysql.h" +extern char const * mysql_error(MYSQL * mysql); +# 541 "mysql.h" +extern unsigned long int mysql_escape_string(char * to, char const * from, unsigned long int); +# 538 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_field(MYSQL_RES * result); +# 403 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_field_direct(MYSQL_RES * res, unsigned int); +# 405 "mysql.h" +extern MYSQL_FIELD * mysql_fetch_fields(MYSQL_RES * res); +# 537 "mysql.h" +extern unsigned long int * mysql_fetch_lengths(MYSQL_RES * result); +# 536 "mysql.h" +extern MYSQL_ROW mysql_fetch_row(MYSQL_RES * result); +# 409 "mysql.h" +extern unsigned int mysql_field_count(MYSQL * mysql); +# 534 "mysql.h" +extern MYSQL_FIELD_OFFSET mysql_field_seek(MYSQL_RES * result, MYSQL_FIELD_OFFSET); +# 407 "mysql.h" +extern MYSQL_FIELD_OFFSET mysql_field_tell(MYSQL_RES * res); +# 529 "mysql.h" +extern void mysql_free_result(MYSQL_RES * result); +# 454 "mysql.h" +extern void mysql_get_character_set_info(MYSQL * mysql, MY_CHARSET_INFO * charset); +# 519 "mysql.h" +extern char const * mysql_get_client_info(void); +# 520 "mysql.h" +extern unsigned long int mysql_get_client_version(void); +# 521 "mysql.h" +extern char const * mysql_get_host_info(MYSQL * mysql); +# 384 "mysql.h" +extern MYSQL_PARAMETERS * mysql_get_parameters(void); +# 523 "mysql.h" +extern unsigned int mysql_get_proto_info(MYSQL * mysql); +# 518 "mysql.h" +extern char const * mysql_get_server_info(MYSQL * mysql); +# 522 "mysql.h" +extern unsigned long int mysql_get_server_version(MYSQL * mysql); +# 425 "mysql.h" +extern char const * mysql_get_ssl_cipher(MYSQL * mysql); +# 543 "mysql.h" +extern unsigned long int mysql_hex_string(char * to, char const * from, unsigned long int); +# 416 "mysql.h" +extern char const * mysql_info(MYSQL * mysql); +# 421 "mysql.h" +extern MYSQL * mysql_init(MYSQL * mysql); +# 411 "mysql.h" +extern my_ulonglong mysql_insert_id(MYSQL * mysql); +# 512 "mysql.h" +extern int mysql_kill(MYSQL * mysql, unsigned long int); +# 524 "mysql.h" +extern MYSQL_RES * mysql_list_dbs(MYSQL * mysql, char const * wild); +# 539 "mysql.h" +extern MYSQL_RES * mysql_list_fields(MYSQL * mysql, char const * table, char const * wild); +# 526 "mysql.h" +extern MYSQL_RES * mysql_list_processes(MYSQL * mysql); +# 525 "mysql.h" +extern MYSQL_RES * mysql_list_tables(MYSQL * mysql, char const * wild); +# 568 "mysql.h" +extern void mysql_manager_close(MYSQL_MANAGER * con); +# 569 "mysql.h" +extern int mysql_manager_command(MYSQL_MANAGER * con, char const * cmd, int); +# 563 "mysql.h" +extern MYSQL_MANAGER * mysql_manager_connect(MYSQL_MANAGER * con, char const * host, char const * user, char const * passwd, unsigned int); +# 571 "mysql.h" +extern int mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int); +# 562 "mysql.h" +extern MYSQL_MANAGER * mysql_manager_init(MYSQL_MANAGER * con); +# 445 "mysql.h" +extern my_bool mysql_master_query(MYSQL * mysql, char const * q, unsigned long int); +# 447 "mysql.h" +extern my_bool mysql_master_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 824 "mysql.h" +extern my_bool mysql_more_results(MYSQL * mysql); +# 825 "mysql.h" +extern int mysql_next_result(MYSQL * mysql); +# 401 "mysql.h" +extern unsigned int mysql_num_fields(MYSQL_RES * res); +# 400 "mysql.h" +extern my_ulonglong mysql_num_rows(MYSQL_RES * res); +# 549 "mysql.h" +extern char * mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long int, char const * from, unsigned long int, void * param, char * (* extend_buffer)(void *, char * to, unsigned long int * length)); +# 527 "mysql.h" +extern int mysql_options(MYSQL * mysql, enum mysql_option, char const * arg); +# 516 "mysql.h" +extern int mysql_ping(MYSQL * mysql); +# 75 "mysql.h" +extern unsigned int mysql_port; +# 436 "mysql.h" +extern int mysql_query(MYSQL * mysql, char const * q); +# 574 "mysql.h" +extern my_bool mysql_read_query_result(MYSQL * mysql); +# 489 "mysql.h" +extern my_bool mysql_reads_from_master_enabled(MYSQL * mysql); +# 428 "mysql.h" +extern MYSQL * mysql_real_connect(MYSQL * mysql, char const * host, char const * user, char const * passwd, char const * db, unsigned int, char const * unix_socket, unsigned long int); +# 545 "mysql.h" +extern unsigned long int mysql_real_escape_string(MYSQL * mysql, char * to, char const * from, unsigned long int); +# 439 "mysql.h" +extern int mysql_real_query(MYSQL * mysql, char const * q, unsigned long int); +# 510 "mysql.h" +extern int mysql_refresh(MYSQL * mysql, unsigned int); +# 822 "mysql.h" +extern my_bool mysql_rollback(MYSQL * mysql); +# 532 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET); +# 406 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_row_tell(MYSQL_RES * res); +# 483 "mysql.h" +extern int mysql_rpl_parse_enabled(MYSQL * mysql); +# 494 "mysql.h" +extern my_bool mysql_rpl_probe(MYSQL * mysql); +# 491 "mysql.h" +extern enum mysql_rpl_type mysql_rpl_query_type(char const * q, int); +# 435 "mysql.h" +extern int mysql_select_db(MYSQL * mysql, char const * db); +# 437 "mysql.h" +extern int mysql_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 371 "mysql.h" +extern void mysql_server_end(void); +# 370 "mysql.h" +extern int mysql_server_init(int, char * * argv, char * * groups); +# 419 "mysql.h" +extern int mysql_set_character_set(MYSQL * mysql, char const * csname); +# 472 "mysql.h" +extern void mysql_set_local_infile_default(MYSQL * mysql); +# 461 "mysql.h" +extern void mysql_set_local_infile_handler(MYSQL * mysql, int (* local_infile_init)(void * *, char const *, void *), int (* local_infile_read)(void *, char *, unsigned int), void (* local_infile_end)(void), int (* local_infile_error)(void *, char *, unsigned int), void *); +# 497 "mysql.h" +extern int mysql_set_master(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); +# 513 "mysql.h" +extern int mysql_set_server_option(MYSQL * mysql, enum enum_mysql_set_option); +# 506 "mysql.h" +extern int mysql_shutdown(MYSQL * mysql, enum mysql_enum_shutdown_level); +# 450 "mysql.h" +extern my_bool mysql_slave_query(MYSQL * mysql, char const * q, unsigned long int); +# 452 "mysql.h" +extern my_bool mysql_slave_send_query(MYSQL * mysql, char const * q, unsigned long int); +# 414 "mysql.h" +extern char const * mysql_sqlstate(MYSQL * mysql); +# 422 "mysql.h" +extern my_bool mysql_ssl_set(MYSQL * mysql, char const * key, char const * cert, char const * ca, char const * capath, char const * cipher); +# 517 "mysql.h" +extern char const * mysql_stat(MYSQL * mysql); +# 817 "mysql.h" +extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt); +# 795 "mysql.h" +extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr); +# 792 "mysql.h" +extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr); +# 798 "mysql.h" +extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 799 "mysql.h" +extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 800 "mysql.h" +extern my_bool mysql_stmt_close(MYSQL_STMT * stmt); +# 815 "mysql.h" +extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong); +# 809 "mysql.h" +extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt); +# 810 "mysql.h" +extern char const * mysql_stmt_error(MYSQL_STMT * stmt); +# 785 "mysql.h" +extern int mysql_stmt_execute(MYSQL_STMT * stmt); +# 786 "mysql.h" +extern int mysql_stmt_fetch(MYSQL_STMT * stmt); +# 787 "mysql.h" +extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind, unsigned int, unsigned long int); +# 819 "mysql.h" +extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt); +# 802 "mysql.h" +extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt); +# 782 "mysql.h" +extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql); +# 818 "mysql.h" +extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt); +# 816 "mysql.h" +extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt); +# 791 "mysql.h" +extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt); +# 808 "mysql.h" +extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt); +# 783 "mysql.h" +extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int); +# 801 "mysql.h" +extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt); +# 807 "mysql.h" +extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt); +# 812 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET); +# 814 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt); +# 803 "mysql.h" +extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int); +# 811 "mysql.h" +extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt); +# 790 "mysql.h" +extern int mysql_stmt_store_result(MYSQL_STMT * stmt); +# 441 "mysql.h" +extern MYSQL_RES * mysql_store_result(MYSQL * mysql); +# 393 "mysql.h" +extern void mysql_thread_end(void); +# 417 "mysql.h" +extern unsigned long int mysql_thread_id(MYSQL * mysql); +# 392 "mysql.h" +extern my_bool mysql_thread_init(void); +# 560 "mysql.h" +extern unsigned int mysql_thread_safe(void); +# 76 "mysql.h" +extern char * mysql_unix_port; +# 442 "mysql.h" +extern MYSQL_RES * mysql_use_result(MYSQL * mysql); +# 415 "mysql.h" extern unsigned int mysql_warning_count(MYSQL * mysql); -# 284 "mysql_com.h" +# 339 "mysql_com.h" extern void net_clear(NET * net); -# 283 "mysql_com.h" +# 338 "mysql_com.h" extern void net_end(NET * net); -# 286 "mysql_com.h" +# 341 "mysql_com.h" extern my_bool net_flush(NET * net); -# 291 "mysql_com.h" +# 346 "mysql_com.h" extern int net_real_write(NET * net, char const * packet, unsigned long int); -# 285 "mysql_com.h" +# 340 "mysql_com.h" extern my_bool net_realloc(NET * net, unsigned long int); -# 755 "mysql.h" -extern unsigned long int net_safe_read(MYSQL * mysql); -# 288 "mysql_com.h" +# 343 "mysql_com.h" extern my_bool net_write_command(NET * net, unsigned char, char const * header, unsigned long int, char const * packet, unsigned long int); +# 427 "mysql_com.h" +extern char * octet2hex(char * to, char const * str, unsigned int); # 121 "/usr/include/sys/select.h" extern int pselect(int, fd_set * restrict __readfds, fd_set * restrict __writefds, fd_set * restrict __exceptfds, struct timespec const * restrict __timeout, __sigset_t const * restrict __sigmask); -# 350 "mysql_com.h" +# 408 "mysql_com.h" extern void randominit(struct rand_struct *, unsigned long int, unsigned long int); -# 364 "mysql_com.h" +# 422 "mysql_com.h" extern void scramble(char * to, char const * message, char const * password); -# 357 "mysql_com.h" +# 415 "mysql_com.h" extern void scramble_323(char * to, char const * message, char const * password); # 109 "/usr/include/sys/select.h" extern int select(int, fd_set * restrict __readfds, fd_set * restrict __writefds, fd_set * restrict __exceptfds, struct timeval * restrict __timeout); From 4da54b476959b9b12bb9fa11a272f1b0400cbf32 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 24 Oct 2006 23:39:46 +0200 Subject: [PATCH 206/235] Adapt mysql-test-run.pl to mysqld in 5.1 using "mixed" binlog format by default --- mysql-test/lib/mtr_cases.pl | 1 + mysql-test/mysql-test-run.pl | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 7a01c66305b..17019cfd351 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -565,6 +565,7 @@ our @tags= ["include/have_innodb.inc", "innodb_test", 1], ["include/have_binlog_format_row.inc", "binlog_format", "row"], ["include/have_binlog_format_statement.inc", "binlog_format", "stmt"], + ["include/have_binlog_format_mixed.inc", "binlog_format", "mixed"], ["include/big_test.inc", "big_test", 1], ["include/have_debug.inc", "need_debug", 1], ["include/have_ndb.inc", "ndb_test", 1], diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 72b4fe95132..9fc63e0462b 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -714,12 +714,20 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # NOTE if the default binlog format is changed, this has to be changed $used_binlog_format= "stmt"; + if ( $mysql_version_id >= 50100 ) + { + $used_binlog_format= "mixed"; + } foreach my $arg ( @opt_extra_mysqld_opt ) { if ( defined mtr_match_substring($arg,"binlog-format=row")) { $used_binlog_format= "row"; } + elsif ( defined mtr_match_substring($arg,"binlog-format=stmt")) + { + $used_binlog_format= "stmt"; + } } mtr_report("Using binlog format '$used_binlog_format'"); From 425277085496e49f65671779ef288eddce7f53c7 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 02:24:08 +0200 Subject: [PATCH 207/235] partition.teest does not use innodb thus it can be run even without innodb --- mysql-test/t/partition.test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/t/partition.test b/mysql-test/t/partition.test index e66dcde71d2..8cb5e76d85b 100644 --- a/mysql-test/t/partition.test +++ b/mysql-test/t/partition.test @@ -4,7 +4,7 @@ # Taken fromm the select test # -- source include/have_partition.inc --- source include/have_innodb.inc + # # This test is disabled on Windows due to BUG#19107 # From 379809f40efff336dfa7c539c3e3c3407e823740 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 12:40:33 +0200 Subject: [PATCH 208/235] Set flag opt_skip_ndbcluster_slave if no slaves are being used. Add comments Deperlify --- mysql-test/mysql-test-run.pl | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 9fc63e0462b..3549c13a2a5 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -405,9 +405,25 @@ sub main () { } $use_innodb||= $test->{'innodb_test'}; } - $opt_skip_ndbcluster= $opt_skip_ndbcluster_slave= 1 - unless $need_ndbcluster; - $opt_skip_im= 1 unless $need_im; + + # Check if cluster can be skipped + if ( !$need_ndbcluster ) + { + $opt_skip_ndbcluster= 1; + $opt_skip_ndbcluster_slave= 1; + } + + # Check if slave cluster can be skipped + if ($max_slave_num == 0) + { + $opt_skip_ndbcluster_slave= 1; + } + + # Check if im can be skipped + if ( ! $need_im ) + { + $opt_skip_im= 1; + } initialize_servers(); From 870ed0c3f5db58c969016fbe6c8492df047f21b5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 14:34:18 +0200 Subject: [PATCH 209/235] Add valgrinding support for mysql_client_test Fix two memory leaks in mysql_client_test mysql-test/mysql-test-run.pl: Add valgrinding support for mysql_client_test tests/mysql_client_test.c: Fix two memory leaks --- mysql-test/mysql-test-run.pl | 98 ++++++++++++++++++++---------------- tests/mysql_client_test.c | 2 + 2 files changed, 56 insertions(+), 44 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3549c13a2a5..dc2c4c1a6fa 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -975,7 +975,7 @@ sub command_line_setup () { } elsif ( $opt_valgrind_mysqltest ) { - mtr_report("Turning on valgrind for mysqltest only"); + mtr_report("Turning on valgrind for mysqltest and mysql_client_test only"); $opt_valgrind= 1; } @@ -1507,6 +1507,47 @@ sub generate_cmdline_mysqldump ($) { # ############################################################################## +sub mysql_client_test_arguments() +{ + my $exe= $exe_mysql_client_test; + + my $args; + mtr_init_args(\$args); + if ( $opt_valgrind_mysqltest ) + { + valgrind_arguments($args, \$exe); + } + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--testcase"); + mtr_add_arg($args, "--user=root"); + mtr_add_arg($args, "--port=$master->[0]->{'port'}"); + mtr_add_arg($args, "--socket=$master->[0]->{'path_sock'}"); + + if ( $mysql_version_id >= 50000 ) + { + mtr_add_arg($args, "--vardir=$opt_vardir") + } + + if ( $opt_debug ) + { + mtr_add_arg($args, + "--debug=d:t:A,$path_vardir_trace/log/mysql_client_test.trace"); + } + + if ( $glob_use_embedded_server ) + { + mtr_add_arg($args, + " -A --language=$path_language"); + mtr_add_arg($args, + " -A --datadir=$slave->[0]->{'path_myddir'}"); + mtr_add_arg($args, + " -A --character-sets-dir=$path_charsetsdir"); + } + + return join(" ", $exe, @$args); +} + # Note that some env is setup in spawn/run, in "mtr_process.pl" sub environment_setup () { @@ -1688,7 +1729,7 @@ sub environment_setup () { "--lock-directory=$opt_tmpdir"; if ( $opt_debug ) - { + { $cmdline_mysqlslap .= " --debug=d:t:A,$path_vardir_trace/log/mysqlslap.trace"; } @@ -1758,30 +1799,7 @@ sub environment_setup () { # ---------------------------------------------------- # Setup env so childs can execute mysql_client_test # ---------------------------------------------------- - my $cmdline_mysql_client_test= - "$exe_mysql_client_test --no-defaults --testcase --user=root " . - "--port=$master->[0]->{'port'} " . - "--socket=$master->[0]->{'path_sock'}"; - if ( $mysql_version_id >= 50000 ) - { - $cmdline_mysql_client_test .=" --vardir=$opt_vardir"; - } - - if ( $opt_debug ) - { - $cmdline_mysql_client_test .= - " --debug=d:t:A,$path_vardir_trace/log/mysql_client_test.trace"; - } - - if ( $glob_use_embedded_server ) - { - $cmdline_mysql_client_test.= - " -A --language=$path_language" . - " -A --datadir=$slave->[0]->{'path_myddir'}" . - " -A --character-sets-dir=$path_charsetsdir"; - } - $ENV{'MYSQL_CLIENT_TEST'}= $cmdline_mysql_client_test; - + $ENV{'MYSQL_CLIENT_TEST'}= mysql_client_test_arguments(); # ---------------------------------------------------- # Setup env so childs can execute mysql_fix_system_tables @@ -3611,15 +3629,6 @@ sub mysqld_start ($$$) { $wait_for_pid_file= 0; } - if ($exe_libtool and $opt_valgrind) - { - # Add "libtool --mode-execute" - # if running in valgrind(to avoid valgrinding bash) - unshift(@$args, "--mode=execute", $exe); - $exe= $exe_libtool; - } - - if ( defined $exe ) { $pid= mtr_spawn($exe, $args, "", @@ -4342,14 +4351,6 @@ sub run_mysqltest ($) { debugger_arguments(\$args, \$exe, "client"); } - if ($exe_libtool and $opt_valgrind) - { - # Add "libtool --mode-execute" before the test to execute - # if running in valgrind(to avoid valgrinding bash) - unshift(@$args, "--mode=execute", $exe); - $exe= $exe_libtool; - } - if ( $opt_check_testcases ) { foreach my $mysqld (@{$master}, @{$slave}) @@ -4575,6 +4576,14 @@ sub valgrind_arguments { mtr_add_arg($args, $$exe); $$exe= $opt_valgrind_path || "valgrind"; + + if ($exe_libtool) + { + # Add "libtool --mode-execute" before the test to execute + # if running in valgrind(to avoid valgrinding bash) + unshift(@$args, "--mode=execute", $$exe); + $$exe= $exe_libtool; + } } @@ -4687,7 +4696,8 @@ Options for coverage, profiling etc valgrind Run the "mysqltest" and "mysqld" executables using valgrind with options($default_valgrind_options) valgrind-all Synonym for --valgrind - valgrind-mysqltest Run the "mysqltest" executable with valgrind + valgrind-mysqltest Run the "mysqltest" and "mysql_client_test" executable + with valgrind valgrind-mysqld Run the "mysqld" executable with valgrind valgrind-options=ARGS Options to give valgrind, replaces default options valgrind-path=[EXE] Path to the valgrind executable diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 64c260666d3..56ab4a63260 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -11778,6 +11778,7 @@ static void test_bug11718() printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE": "not DATE"); DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE); + mysql_free_result(res); rc= mysql_query(mysql, "drop table t1, t2"); myquery(rc); } @@ -11849,6 +11850,7 @@ static void test_bug15613() DIE_UNLESS(field[4].length == 255); DIE_UNLESS(field[5].length == 255); DIE_UNLESS(field[6].length == 255); + mysql_free_result(metadata); /* III. Cleanup */ rc= mysql_query(mysql, "drop table t1"); From 7596e12bbe6cb936f06e7d8893d2bad7276b70cb Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 14:56:36 +0200 Subject: [PATCH 210/235] Update the binlog format parse routine to only be avaliable in 5.1 and allow for any binlog_format to be specified --- mysql-test/mysql-test-run.pl | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index dc2c4c1a6fa..3e25d6e933c 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -732,20 +732,17 @@ sub command_line_setup () { $used_binlog_format= "stmt"; if ( $mysql_version_id >= 50100 ) { - $used_binlog_format= "mixed"; - } - foreach my $arg ( @opt_extra_mysqld_opt ) - { - if ( defined mtr_match_substring($arg,"binlog-format=row")) + $used_binlog_format= "mixed"; # Default value for binlog format + + foreach my $arg ( @opt_extra_mysqld_opt ) { - $used_binlog_format= "row"; - } - elsif ( defined mtr_match_substring($arg,"binlog-format=stmt")) - { - $used_binlog_format= "stmt"; + if ( $arg =~ /binlog-format=(\S+)/ ) + { + $used_binlog_format= $1; + } } + mtr_report("Using binlog format '$used_binlog_format'"); } - mtr_report("Using binlog format '$used_binlog_format'"); # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs From bf6e47f8c4116ad964ee2121d26d61a274fdeae1 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 15:41:32 +0200 Subject: [PATCH 211/235] Test failure when compiled without innodb Disable warnings around the create table statements, we want to use innodb when possible but they work just fine without. mysql-test/t/ctype_utf8.test: Disable warnings around the create table statements, we want to use innodb when possible but they work just fine without. --- mysql-test/t/ctype_utf8.test | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 5dc3e6d5eb2..f4017f314bc 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1162,17 +1162,21 @@ drop table if exists t1; # Bug#19960: Inconsistent results when joining # InnoDB tables using partial UTF8 indexes # +--disable_warnings CREATE TABLE t1 ( colA int(11) NOT NULL, colB varchar(255) character set utf8 NOT NULL, PRIMARY KEY (colA) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +--enable_warnings INSERT INTO t1 (colA, colB) VALUES (1, 'foo'), (2, 'foo bar'); +--disable_warnings CREATE TABLE t2 ( colA int(11) NOT NULL, colB varchar(255) character set utf8 NOT NULL, KEY bad (colA,colB(3)) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +--enable_warnings INSERT INTO t2 (colA, colB) VALUES (1, 'foo'),(2, 'foo bar'); SELECT * FROM t1 JOIN t2 ON t1.colA=t2.colA AND t1.colB=t2.colB WHERE t1.colA < 3; From e6440d1336ca1a9bbd1c7ed95c19d1fb90e03819 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 16:26:57 +0200 Subject: [PATCH 212/235] Fix memory leaks found when valgrinding mysql_client_test Remove one warning tests/mysql_client_test.c: Fix memory leaks Remove one warning --- tests/mysql_client_test.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 96fdb9a4696..da7fde469ad 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -14480,6 +14480,7 @@ static void test_bug11718() printf("return type: %s", (res->fields[0].type == MYSQL_TYPE_DATE)?"DATE": "not DATE"); DIE_UNLESS(res->fields[0].type == MYSQL_TYPE_DATE); + mysql_free_result(res); rc= mysql_query(mysql, "drop table t1, t2"); myquery(rc); } @@ -14928,6 +14929,8 @@ static void test_bug15613() DIE_UNLESS(field[4].length == 255); DIE_UNLESS(field[5].length == 255); DIE_UNLESS(field[6].length == 255); + mysql_free_result(metadata); + mysql_stmt_free_result(stmt); /* III. Cleanup */ rc= mysql_query(mysql, "drop table t1"); @@ -15104,6 +15107,9 @@ static void test_bug14169() if (!opt_silent) printf("GROUP_CONCAT() result type %i", field[1].type); DIE_UNLESS(field[1].type == MYSQL_TYPE_BLOB); + mysql_free_result(res); + mysql_stmt_free_result(stmt); + mysql_stmt_close(stmt); rc= mysql_query(mysql, "drop table t1"); myquery(rc); @@ -15168,7 +15174,7 @@ static void test_bug15752() MYSQL mysql_local; int rc, i; const int ITERATION_COUNT= 100; - char *query= "CALL p1()"; + const char *query= "CALL p1()"; myheader("test_bug15752"); From 5decebc5f3aa6fc2584f6fcbd81ab7e42b63ede5 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 16:50:06 +0200 Subject: [PATCH 213/235] Skip innodb test if mysqld doesn't have innodb support --- mysql-test/lib/mtr_cases.pl | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 17019cfd351..d270d72d526 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -554,6 +554,18 @@ sub collect_one_test_case($$$$$$$) { } } + if ( $tinfo->{'innodb_test'} ) + { + # This is a test that need inndob + if ( $::mysqld_variables{'innodb'} eq "FALSE" ) + { + # innodb is not supported, skip it + $tinfo->{'skip'}= 1; + $tinfo->{'comment'}= "No innodb support"; + return; + } + } + } } From 83ebd23ee9dd23c347787f1895d06e760e123a77 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 25 Oct 2006 18:51:50 -0600 Subject: [PATCH 214/235] BitKeeper/triggers/*crash-protect.pl: Don't print messages if nothing is wrong. BitKeeper/triggers/pre-outgoing.crash-protect.pl: Don't print message if nothing is wrong. BitKeeper/triggers/pre-resolve.crash-protect.pl: Don't print message if nothing is wrong. --- BitKeeper/triggers/pre-outgoing.crash-protect.pl | 4 ---- BitKeeper/triggers/pre-resolve.crash-protect.pl | 4 ---- 2 files changed, 8 deletions(-) diff --git a/BitKeeper/triggers/pre-outgoing.crash-protect.pl b/BitKeeper/triggers/pre-outgoing.crash-protect.pl index bbaa092e335..80567012c0f 100755 --- a/BitKeeper/triggers/pre-outgoing.crash-protect.pl +++ b/BitKeeper/triggers/pre-outgoing.crash-protect.pl @@ -9,8 +9,6 @@ unless($event eq 'outgoing pull' || $event eq 'outgoing push' || exit 0; } -print "Checking for bad changesets from old crashed 5.1 tree...\n"; - my @bad_csets= ( 'monty@mysql.com|ChangeSet|20060418090255|16983', 'monty@mysql.com|ChangeSet|20060418090458|02628', @@ -80,6 +78,4 @@ END } } -print "No bad changesets found, proceeding.\n"; - exit 0; diff --git a/BitKeeper/triggers/pre-resolve.crash-protect.pl b/BitKeeper/triggers/pre-resolve.crash-protect.pl index bbaa092e335..80567012c0f 100755 --- a/BitKeeper/triggers/pre-resolve.crash-protect.pl +++ b/BitKeeper/triggers/pre-resolve.crash-protect.pl @@ -9,8 +9,6 @@ unless($event eq 'outgoing pull' || $event eq 'outgoing push' || exit 0; } -print "Checking for bad changesets from old crashed 5.1 tree...\n"; - my @bad_csets= ( 'monty@mysql.com|ChangeSet|20060418090255|16983', 'monty@mysql.com|ChangeSet|20060418090458|02628', @@ -80,6 +78,4 @@ END } } -print "No bad changesets found, proceeding.\n"; - exit 0; From ac2f1cca69749f85e4436aaf39943b119c0a7f81 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 14:51:34 +0500 Subject: [PATCH 215/235] Fix for bug #22158: Errors in init_connect terminate connections silently When executing the init_connect statement, thd->net.vio is set to 0, to forbid sending any results to the client. As a side effect we don't log possible errors, either. Now we write warnings to the error log if an init_connect query fails. sql/sql_parse.cc: Fix for bug #22158: Errors in init_connect terminate connections silently - raise warnings if the init_connect execution fails. --- sql/sql_parse.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2f1aaea37d0..4992d2514c9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1168,7 +1168,14 @@ pthread_handler_t handle_one_connection(void *arg) { execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect); if (thd->query_error) + { thd->killed= THD::KILL_CONNECTION; + sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION), + thd->thread_id,(thd->db ? thd->db : "unconnected"), + sctx->user ? sctx->user : "unauthenticated", + sctx->host_or_ip, "init_connect command failed"); + sql_print_warning("%s", net->last_error); + } thd->proc_info=0; thd->set_time(); thd->init_for_queries(); From 69f3bb67f572d0b55f5bf49cb90aedb62412568c Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 18:34:24 +0200 Subject: [PATCH 216/235] Bug #14262 SP: DROP PROCEDURE|VIEW (maybe more) write to binlog too late (race cond) - Rmove duplicate code to log a "DROP VIEW..", must be a merge miss sql/sql_view.cc: The query should only be logged to binlog once and that is if the drop didn't produce any errors Removing the duplicate as that must have been a merge error --- sql/sql_view.cc | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sql/sql_view.cc b/sql/sql_view.cc index e3951e78df8..19072bc0fc5 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1418,13 +1418,6 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) sp_cache_invalidate(); } - if (mysql_bin_log.is_open()) - { - thd->clear_error(); - thd->binlog_query(THD::MYSQL_QUERY_TYPE, - thd->query, thd->query_length, FALSE, FALSE); - } - if (error) { VOID(pthread_mutex_unlock(&LOCK_open)); From ed53c394f93444e4f8a11114c0a5f3d426c6220b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 19:11:09 +0200 Subject: [PATCH 217/235] Bug#18888 Trying to overwrite sql/lex_hash.h during build - As a sideeffect of the patch to generate lex_hash.h only once on the machine where the source dist was produced, a problem was found when compiling a mysqld without partition support - it would crash when looking up the lex symbols due to mismatch between lex.h and the generated lex_hash.h - Remove the ifdef for partition in lex.h - Fix minor problem with"EXPLAIN PARTITION" when not compiled with partition(existed also without the above patch) - Add test case that will be run when we don't have partition support compiled into mysqld - Return error ER_FEATURE_DISABLED if user tries to use PARTITION when there is no support for it. sql/lex.h: There should be no ifdefs of features in lex.h sql/sql_class.cc: In line with the comment in sql_yacc.yy that we want the same output from "EXPLAIN PARTITIONS.." regardless of wheter we have compiled in support for partition or not, remove the ifdef so the extra field is added to output if the DESCRIBE_PARTITIONS bit it set. Without this patch we get a crash as the code in select_describe believes the field is there. sql/sql_select.cc: Use "const" for the variable as it's a ssigned once and never changes sql/sql_yacc.yy: Don't allow PARTITION syntax oif there is no suport for partitioning mysql-test/r/not_partition.require: New BitKeeper file ``mysql-test/r/not_partition.require'' mysql-test/r/not_partition.result: New BitKeeper file ``mysql-test/r/not_partition.result'' mysql-test/t/not_partition.test: New BitKeeper file ``mysql-test/t/not_partition.test'' --- mysql-test/r/not_partition.require | 2 + mysql-test/r/not_partition.result | 48 +++++++++++++++++++++++ mysql-test/t/not_partition.test | 62 ++++++++++++++++++++++++++++++ sql/lex.h | 6 ++- sql/sql_class.cc | 2 - sql/sql_select.cc | 2 +- sql/sql_yacc.yy | 7 ++++ 7 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 mysql-test/r/not_partition.require create mode 100644 mysql-test/r/not_partition.result create mode 100644 mysql-test/t/not_partition.test diff --git a/mysql-test/r/not_partition.require b/mysql-test/r/not_partition.require new file mode 100644 index 00000000000..808242277cb --- /dev/null +++ b/mysql-test/r/not_partition.require @@ -0,0 +1,2 @@ +Variable_name Value +have_partitioning NO diff --git a/mysql-test/r/not_partition.result b/mysql-test/r/not_partition.result new file mode 100644 index 00000000000..9e205a09d78 --- /dev/null +++ b/mysql-test/r/not_partition.result @@ -0,0 +1,48 @@ +CREATE TABLE t1 ( +firstname VARCHAR(25) NOT NULL, +lastname VARCHAR(25) NOT NULL, +username VARCHAR(16) NOT NULL, +email VARCHAR(35), +joined DATE NOT NULL +) +PARTITION BY KEY(joined) +PARTITIONS 6; +ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working +ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2; +ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working +drop table t1; +ERROR 42S02: Unknown table 't1' +CREATE TABLE t1 ( +firstname VARCHAR(25) NOT NULL, +lastname VARCHAR(25) NOT NULL, +username VARCHAR(16) NOT NULL, +email VARCHAR(35), +joined DATE NOT NULL +) +PARTITION BY RANGE( YEAR(joined) ) ( +PARTITION p0 VALUES LESS THAN (1960), +PARTITION p1 VALUES LESS THAN (1970), +PARTITION p2 VALUES LESS THAN (1980), +PARTITION p3 VALUES LESS THAN (1990), +PARTITION p4 VALUES LESS THAN MAXVALUE +); +ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working +drop table t1; +ERROR 42S02: Unknown table 't1' +CREATE TABLE t1 (id INT, purchased DATE) +PARTITION BY RANGE( YEAR(purchased) ) +SUBPARTITION BY HASH( TO_DAYS(purchased) ) +SUBPARTITIONS 2 ( +PARTITION p0 VALUES LESS THAN (1990), +PARTITION p1 VALUES LESS THAN (2000), +PARTITION p2 VALUES LESS THAN MAXVALUE +); +ERROR HY000: The 'partitioning' feature is disabled; you need MySQL built with '--with-partition' to have it working +drop table t1; +ERROR 42S02: Unknown table 't1' +create table t1 (a varchar(10) charset latin1 collate latin1_bin); +insert into t1 values (''),(' '),('a'),('a '),('a '); +explain partitions select * from t1 where a='a ' OR a='a'; +id select_type table partitions type possible_keys key key_len ref rows Extra +1 SIMPLE t1 NULL ALL NULL NULL NULL NULL 5 Using where +drop table t1; diff --git a/mysql-test/t/not_partition.test b/mysql-test/t/not_partition.test new file mode 100644 index 00000000000..992615c06f4 --- /dev/null +++ b/mysql-test/t/not_partition.test @@ -0,0 +1,62 @@ +--disable_abort_on_error +# Run this tets only when mysqld don't has partitioning +# the statements are not expected to work, just check that we +# can't crash the server +-- require r/not_partition.require +disable_query_log; +show variables like "have_partitioning"; +enable_query_log; + + +--error ER_FEATURE_DISABLED +CREATE TABLE t1 ( + firstname VARCHAR(25) NOT NULL, + lastname VARCHAR(25) NOT NULL, + username VARCHAR(16) NOT NULL, + email VARCHAR(35), + joined DATE NOT NULL +) +PARTITION BY KEY(joined) +PARTITIONS 6; + +--error ER_FEATURE_DISABLED +ALTER TABLE t1 PARTITION BY KEY(joined) PARTITIONS 2; + +--error ER_BAD_TABLE_ERROR +drop table t1; + +--error ER_FEATURE_DISABLED +CREATE TABLE t1 ( + firstname VARCHAR(25) NOT NULL, + lastname VARCHAR(25) NOT NULL, + username VARCHAR(16) NOT NULL, + email VARCHAR(35), + joined DATE NOT NULL +) +PARTITION BY RANGE( YEAR(joined) ) ( + PARTITION p0 VALUES LESS THAN (1960), + PARTITION p1 VALUES LESS THAN (1970), + PARTITION p2 VALUES LESS THAN (1980), + PARTITION p3 VALUES LESS THAN (1990), + PARTITION p4 VALUES LESS THAN MAXVALUE +); +--error ER_BAD_TABLE_ERROR +drop table t1; + +--error ER_FEATURE_DISABLED +CREATE TABLE t1 (id INT, purchased DATE) + PARTITION BY RANGE( YEAR(purchased) ) + SUBPARTITION BY HASH( TO_DAYS(purchased) ) + SUBPARTITIONS 2 ( + PARTITION p0 VALUES LESS THAN (1990), + PARTITION p1 VALUES LESS THAN (2000), + PARTITION p2 VALUES LESS THAN MAXVALUE + ); +--error ER_BAD_TABLE_ERROR +drop table t1; + +# Create a table without partitions to test "EXPLAIN PARTITIONS" +create table t1 (a varchar(10) charset latin1 collate latin1_bin); +insert into t1 values (''),(' '),('a'),('a '),('a '); +explain partitions select * from t1 where a='a ' OR a='a'; +drop table t1; diff --git a/sql/lex.h b/sql/lex.h index f19c9413e0e..711becc123f 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -45,6 +45,10 @@ SYM_GROUP sym_group_rtree= {"RTree keys", "HAVE_RTREE_KEYS"}; Symbols are broken into separated arrays to allow field names with same name as functions. These are kept sorted for human lookup (the symbols are hashed). + + NOTE! The symbol tables should be the same regardless of what features + are compiled into the server. Don't add ifdef'ed symbols to the + lists */ static SYMBOL symbols[] = { @@ -383,11 +387,9 @@ static SYMBOL symbols[] = { { "PACK_KEYS", SYM(PACK_KEYS_SYM)}, { "PARSER", SYM(PARSER_SYM)}, { "PARTIAL", SYM(PARTIAL)}, -#ifdef WITH_PARTITION_STORAGE_ENGINE { "PARTITION", SYM(PARTITION_SYM)}, { "PARTITIONING", SYM(PARTITIONING_SYM)}, { "PARTITIONS", SYM(PARTITIONS_SYM)}, -#endif { "PASSWORD", SYM(PASSWORD)}, { "PHASE", SYM(PHASE_SYM)}, { "PLUGIN", SYM(PLUGIN_SYM)}, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index dcb3620f329..e1904527866 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -859,7 +859,6 @@ int THD::send_explain_fields(select_result *result) field_list.push_back(new Item_empty_string("select_type", 19, cs)); field_list.push_back(item= new Item_empty_string("table", NAME_LEN, cs)); item->maybe_null= 1; -#ifdef WITH_PARTITION_STORAGE_ENGINE if (lex->describe & DESCRIBE_PARTITIONS) { /* Maximum length of string that make_used_partitions_str() can produce */ @@ -868,7 +867,6 @@ int THD::send_explain_fields(select_result *result) field_list.push_back(item); item->maybe_null= 1; } -#endif field_list.push_back(item= new Item_empty_string("type", 10, cs)); item->maybe_null= 1; field_list.push_back(item=new Item_empty_string("possible_keys", diff --git a/sql/sql_select.cc b/sql/sql_select.cc index bc156aa1526..f8b57368430 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2200,7 +2200,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds, continue; } #ifdef WITH_PARTITION_STORAGE_ENGINE - bool no_partitions_used= table->no_partitions_used; + const bool no_partitions_used= table->no_partitions_used; #else const bool no_partitions_used= FALSE; #endif diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 26dea00029a..f61cc3982ad 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -3225,6 +3225,7 @@ opt_partitioning: partitioning: PARTITION_SYM { +#ifdef WITH_PARTITION_STORAGE_ENGINE LEX *lex= Lex; lex->part_info= new partition_info(); if (!lex->part_info) @@ -3236,6 +3237,12 @@ partitioning: { lex->alter_info.flags|= ALTER_PARTITION; } +#else + my_error(ER_FEATURE_DISABLED, MYF(0), + "partitioning", "--with-partition"); + YYABORT; +#endif + } partition ; From 08d43705a6ab99779cab4fa281b45e00017f59b8 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 19:51:29 +0200 Subject: [PATCH 218/235] Bug#20894 Reproducible MySQL client segmentation fault - Add two null bytes in "buff" variable allowing us to call get_arg two times also for strings longer than sizeof(buff) client/mysql.cc: Make sure there are _two_ zero bytes at the end of buff, to allow 'get_arg' to be called twice on long strings. The first time it will mark end of string with a zero and the second time it will "skip ahead" to the first zero, and the find the second one indicating end of buff. mysql-test/r/mysql.result: Update test results mysql-test/t/mysql.test: Add tests for "com_connect" function in mysql Add test reported in bug --- client/mysql.cc | 6 ++++- mysql-test/r/mysql.result | 17 +++++++++++++ mysql-test/t/mysql.test | 53 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index f845038d6b6..bc00b51ed93 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2934,7 +2934,11 @@ com_connect(String *buffer, char *line) bzero(buff, sizeof(buff)); if (buffer) { - strmake(buff, line, sizeof(buff) - 1); + /* + Two null bytes are needed in the end of buff to allow + get_arg to find end of string the second time it's called. + */ + strmake(buff, line, sizeof(buff)-2); tmp= get_arg(buff, 0); if (tmp && *tmp) { diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index 86ac7a8d72d..9115f9a9628 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -162,4 +162,21 @@ select count(*) from t17583; count(*) 1280 drop table t17583; +Test connect without db- or host-name => reconnect +Test connect with dbname only => new dbname, old hostname +ERROR 1064 (42000) at line 1: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'connecttest' at line 1 +Test connect with _invalid_ dbname only => new invalid dbname, old hostname +ERROR 1049 (42000) at line 1: Unknown database 'invalid' +ERROR 1049 (42000) at line 1: Unknown database 'invalid' +Test connect with dbname + hostname +Test connect with dbname + _invalid_ hostname +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno) +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'invalid_hostname' (errno) +The commands reported in the bug report +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyril has found a bug :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno) +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyril has found a bug :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno) +Too long dbname +ERROR 1049 (42000) at line 1: Unknown database 'test_really_long_dbnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' +Too long hostname +ERROR 2005 (HY000) at line 1: Unknown MySQL server host 'cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' (errno) End of 5.0 tests diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 6b2c84f880a..bd77438704a 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -170,4 +170,57 @@ select count(*) from t17583; --exec echo "select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; select count(*) from t17583; " |$MYSQL test >&- drop table t17583; +# +# Bug#20984: Reproducible MySQL client segmentation fault +# + additional tests for the "com_connect" function in mysql +# +# +--echo Test connect without db- or host-name => reconnect +--exec $MYSQL test -e "\r" 2>&1 +--exec $MYSQL test -e "connect" 2>&1 + +--echo Test connect with dbname only => new dbname, old hostname +--exec $MYSQL test -e "\r test" 2>&1 +--exec $MYSQL test -e "connect test" 2>&1 +--exec $MYSQL test -e "\rtest" 2>&1 +--error 1 +--exec $MYSQL test -e "connecttest" 2>&1 + +--echo Test connect with _invalid_ dbname only => new invalid dbname, old hostname +--error 1 +--exec $MYSQL test -e "\r invalid" 2>&1 +--error 1 +--exec $MYSQL test -e "connect invalid" 2>&1 + +--echo Test connect with dbname + hostname +--exec $MYSQL test -e "\r test localhost" 2>&1 +--exec $MYSQL test -e "connect test localhost" 2>&1 + +--echo Test connect with dbname + _invalid_ hostname +# Mask the errno of the error message +--replace_regex /\([0-9]*\)/(errno)/ +--error 1 +--exec $MYSQL test -e "\r test invalid_hostname" 2>&1 +--replace_regex /\([0-9]*\)/(errno)/ +--error 1 +--exec $MYSQL test -e "connect test invalid_hostname" 2>&1 + +--echo The commands reported in the bug report +--replace_regex /\([0-9]*\)/(errno)/ +--error 1 +--exec $MYSQL test -e "\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" 2>&1 + +--replace_regex /\([0-9]*\)/(errno)/ +--error 1 +--exec echo '\r\r\n\r\n cyril\ has\ found\ a\ bug\ :)XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | $MYSQL 2>&1 + +--echo Too long dbname +--error 1 +--exec echo '\r test_really_long_dbnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX localhost' | $MYSQL 2>&1 + +--echo Too long hostname +--replace_regex /\([0-9]*\)/(errno)/ +--error 1 +--exec echo '\r test cyrils_superlonghostnameXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' | $MYSQL 2>&1 + --echo End of 5.0 tests From b4649198da93c0edebbdf21abfa2e156b24bbd2e Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 15:41:47 -0400 Subject: [PATCH 219/235] Post Merge Cleanup --- storage/innobase/include/univ.i | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index 8765987d472..f471fe136b0 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -40,12 +40,21 @@ if we are compiling on Windows. */ # undef VERSION /* Include the header file generated by GNU autoconf */ +#ifndef __WIN__ # include "config.h" +#endif # ifdef HAVE_SCHED_H # include # endif +/* When compiling for Itanium IA64, undefine the flag below to prevent use +of the 32-bit x86 assembler in mutex operations. */ + +#if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) +#define UNIV_CAN_USE_X86_ASSEMBLER +#endif + /* We only try to do explicit inlining of functions with gcc and Microsoft Visual C++ */ From fc72e7623b9b7ce41ab6a63397f7cf8efd91f15b Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 22:20:43 +0200 Subject: [PATCH 220/235] Bug#23427 incompatible ABI change in 5.0.26? - Improve icheck rules in Makefile.am include/Makefile.am: Remove m_ctype from BUILT_SOURCES, it has been in bk for a looong time. Improve the icheck rules - Abort make if icheck fails to compare, very important. - Don't include include files from /usr into the icheck file. Avoids problem when running icheck on different machines. - If no icheck is availabel, touch the mysql_h.ic file so it exists for "make dist" include/mysql_h_abi.ic: Remove all include files from /usr, no need to check that! --- include/Makefile.am | 17 ++- include/mysql_h_abi.ic | 330 ----------------------------------------- 2 files changed, 10 insertions(+), 337 deletions(-) diff --git a/include/Makefile.am b/include/Makefile.am index ccb0c322208..40a24b6cb77 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -15,14 +15,14 @@ # Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, # MA 02111-1307, USA -BUILT_SOURCES = mysql_version.h m_ctype.h my_config.h mysql_h.ic +BUILT_SOURCES = mysql_version.h my_config.h mysql_h.ic pkginclude_HEADERS = my_dbug.h m_string.h my_sys.h my_list.h my_xml.h \ mysql.h mysql_com.h mysql_embed.h \ my_semaphore.h my_pthread.h my_no_pthread.h raid.h \ errmsg.h my_global.h my_net.h my_alloc.h \ my_getopt.h sslopt-longopts.h my_dir.h typelib.h \ sslopt-vars.h sslopt-case.h sql_common.h keycache.h \ - mysql_time.h $(BUILT_SOURCES) + mysql_time.h m_ctype.h $(BUILT_SOURCES) noinst_HEADERS = config-win.h config-os2.h config-netware.h \ heap.h my_bitmap.h\ myisam.h myisampack.h myisammrg.h ft_global.h\ @@ -33,8 +33,8 @@ noinst_HEADERS = config-win.h config-os2.h config-netware.h \ mysql_version.h.in my_handler.h my_time.h decimal.h \ my_user.h my_libwrap.h -# mysql_version.h are generated -CLEANFILES = mysql_version.h my_config.h readline openssl mysql_h.ic +# Remove built files and the symlinked directories +CLEANFILES = $(BUILT_SOURCES) readline openssl # Some include files that may be moved and patched by configure DISTCLEANFILES = sched.h $(CLEANFILES) @@ -57,15 +57,18 @@ dist-hook: # # Create a icheck file for mysql.h -mysql_h.ic: mysql.h +mysql_h.ic: mysql.h mysql_version.h mysql_com.h mysql_time.h my_list.h \ + my_alloc.h typelib.h @set -x; \ if [ @ICHECK@ != no ] ; then \ - @ICHECK@ --canonify -o $@ mysql.h; \ + @ICHECK@ --canonify --skip-from-re /usr/ -o $@ mysql.h; \ + else \ + touch $@; \ fi; # Compare the icheck file to the reference check_abi: mysql_h.ic - @set -x; \ + @set -ex; \ if [ @ICHECK@ != no ] ; then \ @ICHECK@ --compare mysql_h.ic mysql_h_abi.ic; \ fi; \ diff --git a/include/mysql_h_abi.ic b/include/mysql_h_abi.ic index a0369b79b49..0e546acef92 100644 --- a/include/mysql_h_abi.ic +++ b/include/mysql_h_abi.ic @@ -1,5 +1,3 @@ -struct __pthread_internal_slist; -struct __pthread_mutex_s; struct character_set; struct rand_struct; struct st_list; @@ -21,8 +19,6 @@ struct st_typelib; struct st_udf_args; struct st_udf_init; struct st_used_mem; -struct timespec; -struct timeval; enum Item_result; enum enum_cursor_type; enum enum_field_types; @@ -36,16 +32,8 @@ enum mysql_option; enum mysql_protocol_type; enum mysql_rpl_type; enum mysql_status; -# 59 "/usr/include/bits/types.h" -typedef long long int __quad_t; # 134 "mysql.h" typedef struct st_mysql_rows MYSQL_ROWS; -# 55 "/usr/include/sys/select.h" -typedef long int __fd_mask; -# 145 "/usr/include/bits/types.h" -typedef __quad_t __off64_t; -# 60 "/usr/include/bits/types.h" -typedef unsigned long long int __u_quad_t; # 24 "my_list.h" typedef struct st_list LIST; # 251 "mysql.h" @@ -76,71 +64,6 @@ typedef struct st_net NET; typedef struct st_typelib TYPELIB; # 170 "mysql_com.h" typedef struct st_vio Vio; -# 172 "/usr/include/bits/types.h" -typedef long int __blkcnt_t; -# 189 "/usr/include/bits/types.h" -typedef char * __caddr_t; -# 161 "/usr/include/bits/types.h" -typedef int __clockid_t; -# 156 "/usr/include/bits/types.h" -typedef int __daddr_t; -# 137 "/usr/include/bits/types.h" -typedef __u_quad_t __dev_t; -# 176 "/usr/include/bits/types.h" -typedef unsigned long int __fsblkcnt_t; -# 180 "/usr/include/bits/types.h" -typedef unsigned long int __fsfilcnt_t; -# 147 "/usr/include/bits/types.h" -typedef struct __attribute__((aligned(__alignof__(int)))) - { - int __val[2]; - } __fsid_t; -# 139 "/usr/include/bits/types.h" -typedef unsigned int __gid_t; -# 151 "/usr/include/bits/types.h" -typedef unsigned int __id_t; -# 140 "/usr/include/bits/types.h" -typedef unsigned long int __ino_t; -# 158 "/usr/include/bits/types.h" -typedef int __key_t; -# 187 "/usr/include/bits/types.h" -typedef __off64_t __loff_t; -# 142 "/usr/include/bits/types.h" -typedef unsigned int __mode_t; -# 143 "/usr/include/bits/types.h" -typedef unsigned int __nlink_t; -# 144 "/usr/include/bits/types.h" -typedef long int __off_t; -# 146 "/usr/include/bits/types.h" -typedef int __pid_t; -# 28 "/usr/include/bits/sigset.h" -typedef struct __attribute__((aligned(__alignof__(unsigned long int)))) - { - unsigned long int __val[(1024 / (8 * sizeof(unsigned long int)))]; - } __sigset_t; -# 183 "/usr/include/bits/types.h" -typedef int __ssize_t; -# 154 "/usr/include/bits/types.h" -typedef long int __suseconds_t; -# 152 "/usr/include/bits/types.h" -typedef long int __time_t; -# 164 "/usr/include/bits/types.h" -typedef void * __timer_t; -# 34 "/usr/include/bits/types.h" -typedef unsigned char __u_char; -# 36 "/usr/include/bits/types.h" -typedef unsigned int __u_int; -# 37 "/usr/include/bits/types.h" -typedef unsigned long int __u_long; -# 35 "/usr/include/bits/types.h" -typedef unsigned short int __u_short; -# 138 "/usr/include/bits/types.h" -typedef unsigned int __uid_t; -# 67 "/usr/include/sys/select.h" -typedef struct __attribute__((aligned(__alignof__(long int)))) - { - __fd_mask __fds_bits[(1024 / (8 * sizeof(__fd_mask)))]; - } fd_set; # 57 "mysql.h" typedef char * gptr; # 29 "my_list.h" @@ -167,237 +90,6 @@ typedef struct st_udf_args UDF_ARGS; typedef struct st_udf_init UDF_INIT; # 27 "my_alloc.h" typedef struct st_used_mem USED_MEM; -# 173 "/usr/include/bits/types.h" -typedef __quad_t __blkcnt64_t; -# 167 "/usr/include/bits/types.h" -typedef long int __blksize_t; -# 148 "/usr/include/bits/types.h" -typedef long int __clock_t; -# 177 "/usr/include/bits/types.h" -typedef __u_quad_t __fsblkcnt64_t; -# 181 "/usr/include/bits/types.h" -typedef __u_quad_t __fsfilcnt64_t; -# 141 "/usr/include/bits/types.h" -typedef __u_quad_t __ino64_t; -# 42 "/usr/include/bits/types.h" -typedef short int __int16_t; -# 44 "/usr/include/bits/types.h" -typedef int __int32_t; -# 50 "/usr/include/bits/types.h" -typedef long long int __int64_t; -# 40 "/usr/include/bits/types.h" -typedef signed char __int8_t; -# 192 "/usr/include/bits/types.h" -typedef int __intptr_t; -# 46 "/usr/include/bits/pthreadtypes.h" -typedef struct __pthread_internal_slist __pthread_slist_t; -# 188 "/usr/include/bits/types.h" -typedef __quad_t * __qaddr_t; -# 150 "/usr/include/bits/types.h" -typedef __u_quad_t __rlim64_t; -# 149 "/usr/include/bits/types.h" -typedef unsigned long int __rlim_t; -# 23 "/usr/include/bits/sigset.h" -typedef int __sig_atomic_t; -# 195 "/usr/include/bits/types.h" -typedef unsigned int __socklen_t; -# 157 "/usr/include/bits/types.h" -typedef long int __swblk_t; -# 43 "/usr/include/bits/types.h" -typedef unsigned short int __uint16_t; -# 45 "/usr/include/bits/types.h" -typedef unsigned int __uint32_t; -# 51 "/usr/include/bits/types.h" -typedef unsigned long long int __uint64_t; -# 41 "/usr/include/bits/types.h" -typedef unsigned char __uint8_t; -# 153 "/usr/include/bits/types.h" -typedef unsigned int __useconds_t; -# 235 "/usr/include/sys/types.h" -typedef __blkcnt_t blkcnt_t; -# 117 "/usr/include/sys/types.h" -typedef __caddr_t caddr_t; -# 93 "/usr/include/time.h" -typedef __clockid_t clockid_t; -# 116 "/usr/include/sys/types.h" -typedef __daddr_t daddr_t; -# 62 "/usr/include/sys/types.h" -typedef __dev_t dev_t; -# 85 "/usr/include/sys/select.h" -typedef __fd_mask fd_mask; -# 239 "/usr/include/sys/types.h" -typedef __fsblkcnt_t fsblkcnt_t; -# 243 "/usr/include/sys/types.h" -typedef __fsfilcnt_t fsfilcnt_t; -# 41 "/usr/include/sys/types.h" -typedef __fsid_t fsid_t; -# 67 "/usr/include/sys/types.h" -typedef __gid_t gid_t; -# 105 "/usr/include/sys/types.h" -typedef __id_t id_t; -# 50 "/usr/include/sys/types.h" -typedef __ino_t ino_t; -# 196 "/usr/include/sys/types.h" -typedef int int16_t; -# 197 "/usr/include/sys/types.h" -typedef int int32_t; -# 198 "/usr/include/sys/types.h" -typedef int int64_t; -# 195 "/usr/include/sys/types.h" -typedef int int8_t; -# 123 "/usr/include/sys/types.h" -typedef __key_t key_t; -# 46 "/usr/include/sys/types.h" -typedef __loff_t loff_t; -# 72 "/usr/include/sys/types.h" -typedef __mode_t mode_t; -# 77 "/usr/include/sys/types.h" -typedef __nlink_t nlink_t; -# 88 "/usr/include/sys/types.h" -typedef __off_t off_t; -# 100 "/usr/include/sys/types.h" -typedef __pid_t pid_t; -# 39 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - char __size[36]; - long int __align; - } pthread_attr_t; -# 153 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - char __size[20]; - long int __align; - } pthread_barrier_t; -# 159 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(int)))) - { - char __size[4]; - int __align; - } pthread_barrierattr_t; -# 84 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) - { - struct __attribute__((aligned(__alignof__(unsigned long long int)), aligned(__alignof__(void *)))) - { - int __lock; - unsigned int __futex; - unsigned long long int __total_seq; - unsigned long long int __wakeup_seq; - unsigned long long int __woken_seq; - void * __mutex; - unsigned int __nwaiters; - unsigned int __broadcast_seq; - } __data; - char __size[48]; - long long int __align; - } pthread_cond_t; -# 101 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - char __size[4]; - long int __align; - } pthread_condattr_t; -# 109 "/usr/include/bits/pthreadtypes.h" -typedef unsigned int pthread_key_t; -# 54 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - struct __pthread_mutex_s __data; - char __size[24]; - long int __align; - } pthread_mutex_t; -# 75 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - char __size[4]; - long int __align; - } pthread_mutexattr_t; -# 113 "/usr/include/bits/pthreadtypes.h" -typedef int pthread_once_t; -# 119 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - struct __attribute__((aligned(__alignof__(int)))) - { - int __lock; - unsigned int __nr_readers; - unsigned int __readers_wakeup; - unsigned int __writer_wakeup; - unsigned int __nr_readers_queued; - unsigned int __nr_writers_queued; - unsigned int __flags; - int __writer; - } __data; - char __size[32]; - long int __align; - } pthread_rwlock_t; -# 138 "/usr/include/bits/pthreadtypes.h" -typedef union __attribute__((aligned(__alignof__(long int)))) - { - char __size[8]; - long int __align; - } pthread_rwlockattr_t; -# 148 "/usr/include/bits/pthreadtypes.h" -typedef int volatile pthread_spinlock_t; -# 36 "/usr/include/bits/pthreadtypes.h" -typedef unsigned long int pthread_t; -# 39 "/usr/include/sys/types.h" -typedef __quad_t quad_t; -# 206 "/usr/include/sys/types.h" -typedef int register_t; -# 38 "/usr/include/sys/select.h" -typedef __sigset_t sigset_t; -# 214 "/usr/lib/gcc/i386-redhat-linux/4.0.2/include/stddef.h" -typedef unsigned int size_t; -# 110 "/usr/include/sys/types.h" -typedef __ssize_t ssize_t; -# 49 "/usr/include/sys/select.h" -typedef __suseconds_t suseconds_t; -# 77 "/usr/include/time.h" -typedef __time_t time_t; -# 105 "/usr/include/time.h" -typedef __timer_t timer_t; -# 35 "/usr/include/sys/types.h" -typedef __u_char u_char; -# 37 "/usr/include/sys/types.h" -typedef __u_int u_int; -# 202 "/usr/include/sys/types.h" -typedef unsigned int u_int16_t; -# 203 "/usr/include/sys/types.h" -typedef unsigned int u_int32_t; -# 204 "/usr/include/sys/types.h" -typedef unsigned int u_int64_t; -# 201 "/usr/include/sys/types.h" -typedef unsigned int u_int8_t; -# 38 "/usr/include/sys/types.h" -typedef __u_long u_long; -# 40 "/usr/include/sys/types.h" -typedef __u_quad_t u_quad_t; -# 36 "/usr/include/sys/types.h" -typedef __u_short u_short; -# 82 "/usr/include/sys/types.h" -typedef __uid_t uid_t; -# 153 "/usr/include/sys/types.h" -typedef unsigned int uint; -# 151 "/usr/include/sys/types.h" -typedef unsigned long int ulong; -# 152 "/usr/include/sys/types.h" -typedef unsigned short int ushort; -# 46 "/usr/include/bits/pthreadtypes.h" -struct __attribute__((aligned(__alignof__(void *)))) __pthread_internal_slist - { - struct __pthread_internal_slist * __next; - }; -# 54 "/usr/include/bits/pthreadtypes.h" -struct __attribute__((aligned(__alignof__(int)))) __pthread_mutex_s - { - int __lock; - unsigned int __count; - int __owner; - int __kind; - unsigned int __nusers; - }; # 236 "mysql.h" struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) character_set { @@ -762,18 +454,6 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned unsigned int left; unsigned int size; }; -# 121 "/usr/include/time.h" -struct __attribute__((aligned(__alignof__(long int)))) timespec - { - __time_t tv_sec; - long int tv_nsec; - }; -# 69 "/usr/include/bits/time.h" -struct __attribute__((aligned(__alignof__(long int)))) timeval - { - __time_t tv_sec; - __suseconds_t tv_usec; - }; # 368 "mysql_com.h" enum Item_result { @@ -962,12 +642,6 @@ extern void get_salt_from_password_323(unsigned long int * res, char const * pas extern char * get_tty_password(char * opt_message); # 30 "typelib.h" extern char const * get_type(TYPELIB * typelib, unsigned int); -# 41 "/usr/include/sys/sysmacros.h" -extern unsigned int gnu_dev_major(unsigned long long int); -# 53 "/usr/include/sys/sysmacros.h" -extern unsigned long long int gnu_dev_makedev(unsigned int, unsigned int); -# 47 "/usr/include/sys/sysmacros.h" -extern unsigned int gnu_dev_minor(unsigned long long int); # 413 "mysql_com.h" extern void hash_password(unsigned long int * to, char const * password, unsigned int); # 31 "my_list.h" @@ -1282,15 +956,11 @@ extern my_bool net_realloc(NET * net, unsigned long int); extern my_bool net_write_command(NET * net, unsigned char, char const * header, unsigned long int, char const * packet, unsigned long int); # 427 "mysql_com.h" extern char * octet2hex(char * to, char const * str, unsigned int); -# 121 "/usr/include/sys/select.h" -extern int pselect(int, fd_set * restrict __readfds, fd_set * restrict __writefds, fd_set * restrict __exceptfds, struct timespec const * restrict __timeout, __sigset_t const * restrict __sigmask); # 408 "mysql_com.h" extern void randominit(struct rand_struct *, unsigned long int, unsigned long int); # 422 "mysql_com.h" extern void scramble(char * to, char const * message, char const * password); # 415 "mysql_com.h" extern void scramble_323(char * to, char const * message, char const * password); -# 109 "/usr/include/sys/select.h" -extern int select(int, fd_set * restrict __readfds, fd_set * restrict __writefds, fd_set * restrict __exceptfds, struct timeval * restrict __timeout); # 32 "typelib.h" extern TYPELIB sql_protocol_typelib; From 931aa19a077f0b8a5c277141bea938038f48a067 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 26 Oct 2006 23:59:00 +0200 Subject: [PATCH 221/235] Update for 5.1 include/mysql_h_abi.ic: Update for 5.1, don't include the info_buffer it should be an error --- include/mysql_h_abi.ic | 105 ++++++++++++++++++++--------------------- 1 file changed, 50 insertions(+), 55 deletions(-) diff --git a/include/mysql_h_abi.ic b/include/mysql_h_abi.ic index 0e546acef92..51cbb1fb7eb 100644 --- a/include/mysql_h_abi.ic +++ b/include/mysql_h_abi.ic @@ -58,11 +58,11 @@ typedef MYSQL_ROWS * MYSQL_ROW_OFFSET; typedef struct st_mysql_stmt MYSQL_STMT; # 236 "mysql.h" typedef struct character_set MY_CHARSET_INFO; -# 180 "mysql_com.h" +# 184 "mysql_com.h" typedef struct st_net NET; # 21 "typelib.h" typedef struct st_typelib TYPELIB; -# 170 "mysql_com.h" +# 174 "mysql_com.h" typedef struct st_vio Vio; # 57 "mysql.h" typedef char * gptr; @@ -84,9 +84,9 @@ typedef struct st_mysql_data MYSQL_DATA; typedef struct st_mysql_methods MYSQL_METHODS; # 48 "mysql_time.h" typedef struct st_mysql_time MYSQL_TIME; -# 371 "mysql_com.h" +# 375 "mysql_com.h" typedef struct st_udf_args UDF_ARGS; -# 384 "mysql_com.h" +# 388 "mysql_com.h" typedef struct st_udf_init UDF_INIT; # 27 "my_alloc.h" typedef struct st_used_mem USED_MEM; @@ -102,7 +102,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo unsigned int mbminlen; unsigned int mbmaxlen; }; -# 357 "mysql_com.h" +# 361 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(double)))) rand_struct { unsigned long int seed1; @@ -383,7 +383,7 @@ struct __attribute__((aligned(__alignof__(unsigned long int)))) st_mysql_time my_bool neg; enum enum_mysql_timestamp_type time_type; }; -# 180 "mysql_com.h" +# 184 "mysql_com.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_net { Vio * vio; @@ -427,7 +427,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo char const * * type_names; unsigned int * type_lengths; }; -# 371 "mysql_com.h" +# 375 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_udf_args { unsigned int arg_count; @@ -438,7 +438,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo char * * attributes; unsigned long int * attribute_lengths; }; -# 384 "mysql_com.h" +# 388 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_udf_init { my_bool maybe_null; @@ -454,7 +454,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned unsigned int left; unsigned int size; }; -# 368 "mysql_com.h" +# 372 "mysql_com.h" enum Item_result { STRING_RESULT = 0, @@ -463,7 +463,7 @@ enum Item_result ROW_RESULT = 3, DECIMAL_RESULT = 4, }; -# 314 "mysql_com.h" +# 318 "mysql_com.h" enum enum_cursor_type { CURSOR_TYPE_NO_CURSOR = 0, @@ -471,7 +471,7 @@ enum enum_cursor_type CURSOR_TYPE_FOR_UPDATE = 2, CURSOR_TYPE_SCROLLABLE = 4, }; -# 227 "mysql_com.h" +# 231 "mysql_com.h" enum enum_field_types { MYSQL_TYPE_DECIMAL = 0, @@ -502,7 +502,7 @@ enum enum_field_types MYSQL_TYPE_STRING = 254, MYSQL_TYPE_GEOMETRY = 255, }; -# 324 "mysql_com.h" +# 328 "mysql_com.h" enum enum_mysql_set_option { MYSQL_OPTION_MULTI_STATEMENTS_ON = 0, @@ -557,7 +557,8 @@ enum enum_server_command COM_STMT_RESET = 26, COM_SET_OPTION = 27, COM_STMT_FETCH = 28, - COM_END = 29, + COM_DAEMON = 29, + COM_END = 30, }; # 727 "mysql.h" enum enum_stmt_attr_type @@ -566,7 +567,7 @@ enum enum_stmt_attr_type STMT_ATTR_CURSOR_TYPE = 1, STMT_ATTR_PREFETCH_ROWS = 2, }; -# 289 "mysql_com.h" +# 293 "mysql_com.h" enum mysql_enum_shutdown_level { SHUTDOWN_DEFAULT = 0, @@ -626,23 +627,23 @@ enum mysql_status MYSQL_STATUS_GET_RESULT = 1, MYSQL_STATUS_USE_RESULT = 2, }; -# 423 "mysql_com.h" +# 427 "mysql_com.h" extern my_bool check_scramble(char const * reply, char const * message, unsigned char const * hash_stage2); -# 416 "mysql_com.h" +# 420 "mysql_com.h" extern my_bool check_scramble_323(char const *, char const * message, unsigned long int * salt); -# 411 "mysql_com.h" +# 415 "mysql_com.h" extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st); # 28 "typelib.h" extern int find_type(char * x, TYPELIB * typelib, unsigned int); -# 425 "mysql_com.h" +# 429 "mysql_com.h" extern void get_salt_from_password(unsigned char * res, char const * password); -# 418 "mysql_com.h" +# 422 "mysql_com.h" extern void get_salt_from_password_323(unsigned long int * res, char const * password); -# 431 "mysql_com.h" -extern char * get_tty_password(char * opt_message); +# 435 "mysql_com.h" +extern char * get_tty_password(char const * opt_message); # 30 "typelib.h" extern char const * get_type(TYPELIB * typelib, unsigned int); -# 413 "mysql_com.h" +# 417 "mysql_com.h" extern void hash_password(unsigned long int * to, char const * password, unsigned int); # 31 "my_list.h" extern LIST * list_add(LIST * root, LIST * element); @@ -658,37 +659,31 @@ extern unsigned int list_length(LIST *); extern LIST * list_reverse(LIST * root); # 37 "my_list.h" extern int list_walk(LIST *, list_walk_action, gptr); -# 440 "mysql_com.h" -extern int load_defaults(char const * conf_file, char const * * groups, int * argc, char * * * argv); -# 426 "mysql_com.h" +# 430 "mysql_com.h" extern void make_password_from_salt(char * to, unsigned char const * hash_stage2); -# 419 "mysql_com.h" +# 423 "mysql_com.h" extern void make_password_from_salt_323(char * to, unsigned long int const * salt); -# 421 "mysql_com.h" +# 425 "mysql_com.h" extern void make_scrambled_password(char * to, char const * password); -# 414 "mysql_com.h" +# 418 "mysql_com.h" extern void make_scrambled_password_323(char * to, char const * password); # 29 "typelib.h" extern void make_type(char * to, unsigned int, TYPELIB * typelib); -# 437 "mysql_com.h" -extern int modify_defaults_file(char const * file_location, char const * option, char const * option_value, char const * section_name, int); -# 354 "mysql_com.h" +# 358 "mysql_com.h" extern int my_connect(my_socket, struct sockaddr const * name, unsigned int, unsigned int); -# 436 "mysql_com.h" -extern my_bool my_init(void); -# 336 "mysql_com.h" +# 340 "mysql_com.h" extern my_bool my_net_init(NET * net, Vio * vio); -# 337 "mysql_com.h" +# 341 "mysql_com.h" extern void my_net_local_init(NET * net); -# 347 "mysql_com.h" +# 351 "mysql_com.h" extern unsigned long int my_net_read(NET * net); -# 342 "mysql_com.h" +# 346 "mysql_com.h" extern my_bool my_net_write(NET * net, char const * packet, unsigned long int); -# 410 "mysql_com.h" +# 414 "mysql_com.h" extern double my_rnd(struct rand_struct *); -# 443 "mysql_com.h" +# 441 "mysql_com.h" extern void my_thread_end(void); -# 442 "mysql_com.h" +# 440 "mysql_com.h" extern my_bool my_thread_init(void); # 559 "mysql.h" extern void myodbc_remove_escape(MYSQL * mysql, char * name); @@ -726,7 +721,7 @@ extern void mysql_enable_rpl_parse(MYSQL * mysql); extern my_bool mysql_eof(MYSQL_RES * res); # 412 "mysql.h" extern unsigned int mysql_errno(MYSQL * mysql); -# 432 "mysql_com.h" +# 436 "mysql_com.h" extern char const * mysql_errno_to_sqlstate(unsigned int); # 413 "mysql.h" extern char const * mysql_error(MYSQL * mysql); @@ -942,25 +937,25 @@ extern char * mysql_unix_port; extern MYSQL_RES * mysql_use_result(MYSQL * mysql); # 415 "mysql.h" extern unsigned int mysql_warning_count(MYSQL * mysql); -# 339 "mysql_com.h" -extern void net_clear(NET * net); -# 338 "mysql_com.h" -extern void net_end(NET * net); -# 341 "mysql_com.h" -extern my_bool net_flush(NET * net); -# 346 "mysql_com.h" -extern int net_real_write(NET * net, char const * packet, unsigned long int); -# 340 "mysql_com.h" -extern my_bool net_realloc(NET * net, unsigned long int); # 343 "mysql_com.h" +extern void net_clear(NET * net); +# 342 "mysql_com.h" +extern void net_end(NET * net); +# 345 "mysql_com.h" +extern my_bool net_flush(NET * net); +# 350 "mysql_com.h" +extern int net_real_write(NET * net, char const * packet, unsigned long int); +# 344 "mysql_com.h" +extern my_bool net_realloc(NET * net, unsigned long int); +# 347 "mysql_com.h" extern my_bool net_write_command(NET * net, unsigned char, char const * header, unsigned long int, char const * packet, unsigned long int); -# 427 "mysql_com.h" +# 431 "mysql_com.h" extern char * octet2hex(char * to, char const * str, unsigned int); -# 408 "mysql_com.h" +# 412 "mysql_com.h" extern void randominit(struct rand_struct *, unsigned long int, unsigned long int); -# 422 "mysql_com.h" +# 426 "mysql_com.h" extern void scramble(char * to, char const * message, char const * password); -# 415 "mysql_com.h" +# 419 "mysql_com.h" extern void scramble_323(char * to, char const * message, char const * password); # 32 "typelib.h" extern TYPELIB sql_protocol_typelib; From d2c90fcb8ecee24d68df83c83a70c0a8b8ab77c8 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Oct 2006 18:08:50 +0500 Subject: [PATCH 222/235] Fix for bug #23412: delete rows with null date field Backport of the fix for bug #8143: A date with value 0 is treated as a NULL value mysql-test/r/delete.result: Fix for bug #23412: delete rows with null date field - test result mysql-test/t/delete.test: Fix for bug #23412: delete rows with null date field - test case sql/sql_delete.cc: Fix for bug #23412: delete rows with null date field - during SELECT queries processing we convert 'date[time]_field is null' conditions into 'date[time]_field = 0000-00-00[ 00:00:00]' for not null DATE and DATETIME fields. To be consistent, we have to do the same for DELETE queries. So we should call remove_eq_conds() in the mysql_delete() as well. Also it may simplify and speed up DELETE queries execution. --- mysql-test/r/delete.result | 11 +++++++++++ mysql-test/t/delete.test | 13 ++++++++++++- sql/sql_delete.cc | 8 ++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index cb632fcd6c8..7a6af8fd905 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -176,3 +176,14 @@ create table t1 (a int); delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5; delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5; drop table t1; +create table t1(a date not null); +insert into t1 values (0); +select * from t1 where a is null; +a +0000-00-00 +delete from t1 where a is null; +select count(*) from t1; +count(*) +0 +drop table t1; +End of 4.1 tests diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index d4eb01cab23..2036b59d810 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -163,4 +163,15 @@ delete `4.t1` from t1 as `4.t1` where `4.t1`.a = 5; delete FROM `4.t1` USING t1 as `4.t1` where `4.t1`.a = 5; drop table t1; -# End of 4.1 tests +# +# Bug #8143: deleting '0000-00-00' values using IS NULL +# + +create table t1(a date not null); +insert into t1 values (0); +select * from t1 where a is null; +delete from t1 where a is null; +select count(*) from t1; +drop table t1; + +--echo End of 4.1 tests diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b085d37be78..c1455c4b668 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -79,6 +79,14 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, /* Handler didn't support fast delete; Delete rows one by one */ } + if (conds) + { + Item::cond_result result; + conds= remove_eq_conds(thd, conds, &result); + if (result == Item::COND_FALSE) // Impossible where + limit= 0; + } + table->used_keys.clear_all(); table->quick_keys.clear_all(); // Can't use 'only index' select=make_select(table,0,0,conds,&error); From be22efdaef75d3d3bad00ed545fd53a4fd442cbb Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 27 Oct 2006 16:36:08 +0200 Subject: [PATCH 223/235] Disable abi_check in 5.1 for the moment --- include/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/Makefile.am b/include/Makefile.am index 9749c52cc6f..b46e1a8402c 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -76,7 +76,7 @@ check_abi: mysql_h.ic fi; \ touch check_abi; -all: check_abi +#all: check_abi # Don't update the files from bitkeeper From 3e7cae68afbe87b9a7376b2e8b2edbdf952c4a72 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Oct 2006 13:08:57 +0100 Subject: [PATCH 224/235] Add an extra block to avoid that DBUG_ENTER declare variables after code --- myisam/sort.c | 262 ++++++++++++++++++++++++++------------------------ 1 file changed, 134 insertions(+), 128 deletions(-) diff --git a/myisam/sort.c b/myisam/sort.c index cb7893b37bc..35a4f15b23c 100644 --- a/myisam/sort.c +++ b/myisam/sort.c @@ -322,159 +322,165 @@ pthread_handler_t thr_find_all_keys(void *arg) if (my_thread_init()) goto err; - DBUG_ENTER("thr_find_all_keys"); - DBUG_PRINT("enter", ("master: %d", sort_param->master)); - if (sort_param->sort_info->got_error) - goto err; - if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) - { - sort_param->write_keys= write_keys_varlen; - sort_param->read_to_buffer= read_to_buffer_varlen; - sort_param->write_key= write_merge_key_varlen; - } - else - { - sort_param->write_keys= write_keys; - sort_param->read_to_buffer= read_to_buffer; - sort_param->write_key= write_merge_key; - } - my_b_clear(&sort_param->tempfile); - my_b_clear(&sort_param->tempfile_for_exceptions); - bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); - bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); - sort_keys= (uchar **) NULL; + { /* Add extra block since DBUG_ENTER declare variables */ + DBUG_ENTER("thr_find_all_keys"); + DBUG_PRINT("enter", ("master: %d", sort_param->master)); + if (sort_param->sort_info->got_error) + goto err; - memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); - idx= sort_param->sort_info->max_records; - sort_length= sort_param->key_length; - maxbuffer= 1; - - while (memavl >= MIN_SORT_MEMORY) - { - if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= - (my_off_t) memavl) - keys= idx+1; + if (sort_param->keyinfo->flag & HA_VAR_LENGTH_KEY) + { + sort_param->write_keys= write_keys_varlen; + sort_param->read_to_buffer= read_to_buffer_varlen; + sort_param->write_key= write_merge_key_varlen; + } else { - uint skr; - do - { - skr=maxbuffer; - if (memavl < sizeof(BUFFPEK)*maxbuffer || - (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ - (sort_length+sizeof(char*))) <= 1 || - keys < (uint) maxbuffer) - { - mi_check_print_error(sort_param->sort_info->param, - "sort_buffer_size is to small"); - goto err; - } - } - while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); + sort_param->write_keys= write_keys; + sort_param->read_to_buffer= read_to_buffer; + sort_param->write_key= write_merge_key; } - if ((sort_keys= (uchar**) - my_malloc(keys*(sort_length+sizeof(char*))+ - ((sort_param->keyinfo->flag & HA_FULLTEXT) ? - HA_FT_MAXBYTELEN : 0), MYF(0)))) + + my_b_clear(&sort_param->tempfile); + my_b_clear(&sort_param->tempfile_for_exceptions); + bzero((char*) &sort_param->buffpek, sizeof(sort_param->buffpek)); + bzero((char*) &sort_param->unique, sizeof(sort_param->unique)); + sort_keys= (uchar **) NULL; + + memavl= max(sort_param->sortbuff_size, MIN_SORT_MEMORY); + idx= sort_param->sort_info->max_records; + sort_length= sort_param->key_length; + maxbuffer= 1; + + while (memavl >= MIN_SORT_MEMORY) { - if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), - maxbuffer, maxbuffer/2)) - { - my_free((gptr) sort_keys,MYF(0)); - sort_keys= (uchar **) NULL; /* for err: label */ - } + if ((my_off_t) (idx+1)*(sort_length+sizeof(char*)) <= + (my_off_t) memavl) + keys= idx+1; else - break; + { + uint skr; + do + { + skr= maxbuffer; + if (memavl < sizeof(BUFFPEK)*maxbuffer || + (keys=(memavl-sizeof(BUFFPEK)*maxbuffer)/ + (sort_length+sizeof(char*))) <= 1 || + keys < (uint) maxbuffer) + { + mi_check_print_error(sort_param->sort_info->param, + "sort_buffer_size is to small"); + goto err; + } + } + while ((maxbuffer= (int) (idx/(keys-1)+1)) != skr); + } + if ((sort_keys= (uchar**) + my_malloc(keys*(sort_length+sizeof(char*))+ + ((sort_param->keyinfo->flag & HA_FULLTEXT) ? + HA_FT_MAXBYTELEN : 0), MYF(0)))) + { + if (my_init_dynamic_array(&sort_param->buffpek, sizeof(BUFFPEK), + maxbuffer, maxbuffer/2)) + { + my_free((gptr) sort_keys,MYF(0)); + sort_keys= (uchar **) NULL; /* for err: label */ + } + else + break; + } + old_memavl= memavl; + if ((memavl= memavl/4*3) < MIN_SORT_MEMORY && + old_memavl > MIN_SORT_MEMORY) + memavl= MIN_SORT_MEMORY; } - old_memavl=memavl; - if ((memavl=memavl/4*3) < MIN_SORT_MEMORY && old_memavl > MIN_SORT_MEMORY) - memavl=MIN_SORT_MEMORY; - } - if (memavl < MIN_SORT_MEMORY) - { - mi_check_print_error(sort_param->sort_info->param, "Sort buffer too small"); - goto err; /* purecov: tested */ - } - - if (sort_param->sort_info->param->testflag & T_VERBOSE) - printf("Key %d - Allocating buffer for %d keys\n", - sort_param->key + 1, keys); - sort_param->sort_keys= sort_keys; - - idx=error=0; - sort_keys[0]=(uchar*) (sort_keys+keys); - - DBUG_PRINT("info", ("reading keys")); - while (!(error= sort_param->sort_info->got_error) && - !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) - { - if (sort_param->real_key_length > sort_param->key_length) + if (memavl < MIN_SORT_MEMORY) { - if (write_key(sort_param, sort_keys[idx], - &sort_param->tempfile_for_exceptions)) - goto err; - continue; + mi_check_print_error(sort_param->sort_info->param, + "Sort buffer too small"); + goto err; /* purecov: tested */ } - if (++idx == keys) + if (sort_param->sort_info->param->testflag & T_VERBOSE) + printf("Key %d - Allocating buffer for %d keys\n", + sort_param->key + 1, keys); + sort_param->sort_keys= sort_keys; + + idx= error= 0; + sort_keys[0]= (uchar*) (sort_keys+keys); + + DBUG_PRINT("info", ("reading keys")); + while (!(error= sort_param->sort_info->got_error) && + !(error= (*sort_param->key_read)(sort_param, sort_keys[idx]))) { - if (sort_param->write_keys(sort_param, sort_keys, idx - 1, + if (sort_param->real_key_length > sort_param->key_length) + { + if (write_key(sort_param, sort_keys[idx], + &sort_param->tempfile_for_exceptions)) + goto err; + continue; + } + + if (++idx == keys) + { + if (sort_param->write_keys(sort_param, sort_keys, idx - 1, + (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), + &sort_param->tempfile)) + goto err; + sort_keys[0]= (uchar*) (sort_keys+keys); + memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); + idx= 1; + } + sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; + } + if (error > 0) + goto err; + if (sort_param->buffpek.elements) + { + if (sort_param->write_keys(sort_param, sort_keys, idx, (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), &sort_param->tempfile)) goto err; - sort_keys[0]=(uchar*) (sort_keys+keys); - memcpy(sort_keys[0], sort_keys[idx - 1], (size_t) sort_param->key_length); - idx=1; + sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; } - sort_keys[idx]= sort_keys[idx - 1] + sort_param->key_length; - } - if (error > 0) - goto err; - if (sort_param->buffpek.elements) - { - if (sort_param->write_keys(sort_param, sort_keys, idx, - (BUFFPEK*) alloc_dynamic(&sort_param->buffpek), - &sort_param->tempfile)) - goto err; - sort_param->keys= (sort_param->buffpek.elements - 1) * (keys - 1) + idx; - } - else - sort_param->keys= idx; + else + sort_param->keys= idx; - sort_param->sort_keys_length= keys; - goto ok; + sort_param->sort_keys_length= keys; + goto ok; err: - DBUG_PRINT("error", ("got some error")); - sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ - if (sort_keys) - my_free((gptr) sort_keys,MYF(0)); - sort_param->sort_keys= 0; - delete_dynamic(& sort_param->buffpek); - close_cached_file(&sort_param->tempfile); - close_cached_file(&sort_param->tempfile_for_exceptions); + DBUG_PRINT("error", ("got some error")); + sort_param->sort_info->got_error= 1; /* no need to protect with a mutex */ + if (sort_keys) + my_free((gptr) sort_keys,MYF(0)); + sort_param->sort_keys= 0; + delete_dynamic(& sort_param->buffpek); + close_cached_file(&sort_param->tempfile); + close_cached_file(&sort_param->tempfile_for_exceptions); ok: - /* - Detach from the share if the writer is involved. Avoid others to - be blocked. This includes a flush of the write buffer. This will - also indicate EOF to the readers. - */ - if (sort_param->sort_info->info->rec_cache.share) - remove_io_thread(&sort_param->sort_info->info->rec_cache); + /* + Detach from the share if the writer is involved. Avoid others to + be blocked. This includes a flush of the write buffer. This will + also indicate EOF to the readers. + */ + if (sort_param->sort_info->info->rec_cache.share) + remove_io_thread(&sort_param->sort_info->info->rec_cache); - /* Readers detach from the share if any. Avoid others to be blocked. */ - if (sort_param->read_cache.share) - remove_io_thread(&sort_param->read_cache); + /* Readers detach from the share if any. Avoid others to be blocked. */ + if (sort_param->read_cache.share) + remove_io_thread(&sort_param->read_cache); - pthread_mutex_lock(&sort_param->sort_info->mutex); - if (!--sort_param->sort_info->threads_running) - pthread_cond_signal(&sort_param->sort_info->cond); - pthread_mutex_unlock(&sort_param->sort_info->mutex); + pthread_mutex_lock(&sort_param->sort_info->mutex); + if (!--sort_param->sort_info->threads_running) + pthread_cond_signal(&sort_param->sort_info->cond); + pthread_mutex_unlock(&sort_param->sort_info->mutex); - DBUG_PRINT("exit", ("======== ending thread ========")); + DBUG_PRINT("exit", ("======== ending thread ========")); + } my_thread_end(); return NULL; } From e948c64ff52fda43d2a7cb59bc631e53051adc05 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Oct 2006 13:35:57 +0100 Subject: [PATCH 225/235] Improve comments around FLUSH STATUS It's not possible to flush the global status variables in 5.0 Update test case so it works by recording the value of handle_rollback before and compare it to the value after mysql-test/r/innodb_mysql.result: Update result file mysql-test/t/innodb_mysql.test: It's not possible to reset the global status variables in 5.0 so intead its value is recorded and compared to the after value. It should not have changed. sql/mysqld.cc: Improve comments sql/set_var.cc: Improve comments sql/sql_class.cc: Improve comments sql/sql_class.h: Improve comments --- mysql-test/r/innodb_mysql.result | 6 ++---- mysql-test/t/innodb_mysql.test | 9 +++++++-- sql/mysqld.cc | 10 +++++++++- sql/set_var.cc | 2 +- sql/sql_class.cc | 5 ++--- sql/sql_class.h | 9 +++++++-- 6 files changed, 28 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/innodb_mysql.result b/mysql-test/r/innodb_mysql.result index bce5eff5d75..ef67104378c 100644 --- a/mysql-test/r/innodb_mysql.result +++ b/mysql-test/r/innodb_mysql.result @@ -104,14 +104,12 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = id1 2 DROP TABLE t1, t2; -flush status; create table t1 (c1 int) engine=innodb; handler t1 open; handler t1 read first; c1 -show /*!50002 GLOBAL */ status like 'Handler_rollback'; -Variable_name Value -Handler_rollback 0 +Before and after comparison +0 drop table t1; End of 4.1 tests create table t1m (a int) engine=myisam; diff --git a/mysql-test/t/innodb_mysql.test b/mysql-test/t/innodb_mysql.test index ff3089c98cf..73ae4845c06 100644 --- a/mysql-test/t/innodb_mysql.test +++ b/mysql-test/t/innodb_mysql.test @@ -119,7 +119,8 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = DROP TABLE t1, t2; # Bug #22728 - Handler_rollback value is growing # -flush status; + +let $before= `show /*!50002 GLOBAL */ status like 'Handler_rollback'`; create table t1 (c1 int) engine=innodb; connect (con1,localhost,root,,); connect (con2,localhost,root,,); @@ -128,7 +129,11 @@ handler t1 open; handler t1 read first; disconnect con2; connection con1; -show /*!50002 GLOBAL */ status like 'Handler_rollback'; +let $after= `show /*!50002 GLOBAL */ status like 'Handler_rollback'`; +# Compare the before and after value, it should be equal +--disable_query_log +eval select STRCMP("$before", "$after") as "Before and after comparison"; +--enable_query_log connection default; drop table t1; disconnect con1; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 1dd15398cd1..c84e1f7ee56 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -5997,6 +5997,10 @@ The minimum value for this variable is 4096.", }; +/* + Variables shown by SHOW STATUS in alphabetical order +*/ + struct show_var_st status_vars[]= { {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG}, {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG}, @@ -7466,15 +7470,19 @@ void refresh_status(THD *thd) { pthread_mutex_lock(&LOCK_status); - /* We must update the global status before cleaning up the thread */ + /* Add thread's status variabes to global status */ add_to_status(&global_status_var, &thd->status_var); + + /* Reset thread's status variables */ bzero((char*) &thd->status_var, sizeof(thd->status_var)); + /* Reset some global variables */ for (struct show_var_st *ptr=status_vars; ptr->name; ptr++) { if (ptr->type == SHOW_LONG) *(ulong*) ptr->value= 0; } + /* Reset the counters of all key caches (default and named). */ process_key_caches(reset_key_cache_counters); pthread_mutex_unlock(&LOCK_status); diff --git a/sql/set_var.cc b/sql/set_var.cc index df0c69260e7..55c62a9a5a5 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -804,7 +804,7 @@ sys_var *sys_variables[]= /* - Variables shown by SHOW variables in alphabetical order + Variables shown by SHOW VARIABLES in alphabetical order */ struct show_var_st init_vars[]= { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index f5bab1d17f4..ba2f525a4a4 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -464,14 +464,13 @@ THD::~THD() void add_to_status(STATUS_VAR *to_var, STATUS_VAR *from_var) { - ulong *end= (ulong*) ((byte*) to_var + offsetof(STATUS_VAR, - last_system_status_var) + + ulong *end= (ulong*) ((byte*) to_var + + offsetof(STATUS_VAR, last_system_status_var) + sizeof(ulong)); ulong *to= (ulong*) to_var, *from= (ulong*) from_var; while (to != end) *(to++)+= *(from++); - /* it doesn't make sense to add last_query_cost values */ } diff --git a/sql/sql_class.h b/sql/sql_class.h index 62cfb0119aa..c7bdfbd7ea7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -646,12 +646,17 @@ typedef struct system_status_var ulong com_stmt_reset; ulong com_stmt_close; + /* + Status variables which it does not make sense to add to + global status variable counter + */ double last_query_cost; } STATUS_VAR; /* - This is used for 'show status'. It must be updated to the last ulong - variable in system_status_var + This is used for 'SHOW STATUS'. It must be updated to the last ulong + variable in system_status_var which is makes sens to add to the global + counter */ #define last_system_status_var com_stmt_close From c2b8a63ccf70164962fcee3d03824d60f5071b43 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 30 Oct 2006 14:42:28 +0100 Subject: [PATCH 226/235] Bug#18654 Test is timing-dependent and fails from scheduling effects (?) - Wait in loop with small sleep until tables has been renamed mysql-test/t/rename.test: To avoid scheduling effects wait for the tables to be renamed in a loop with small sleeps before continuing with tests mysql-test/include/wait_for_query_to_suceed.inc: New BitKeeper file ``mysql-test/include/wait_for_query_to_suceed.inc'' --- .../include/wait_for_query_to_suceed.inc | 25 +++++++++++++++++++ mysql-test/t/rename.test | 12 ++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) create mode 100644 mysql-test/include/wait_for_query_to_suceed.inc diff --git a/mysql-test/include/wait_for_query_to_suceed.inc b/mysql-test/include/wait_for_query_to_suceed.inc new file mode 100644 index 00000000000..6ac1144620e --- /dev/null +++ b/mysql-test/include/wait_for_query_to_suceed.inc @@ -0,0 +1,25 @@ +# +# Run a query over and over until it suceeds ot timeout occurs +# + + +let $counter= 100; + +disable_abort_on_error; +disable_query_log; +disable_result_log; +eval $query; +while ($mysql_errno) +{ + eval $query; + sleep 0.1; + dec $counter; + + if (!$counter) + { + die("Waited too long for query to suceed"); + } +} +enable_abort_on_error; +enable_query_log; +enable_result_log; diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test index 5caecef176e..b0fb60c0ee4 100644 --- a/mysql-test/t/rename.test +++ b/mysql-test/t/rename.test @@ -43,8 +43,8 @@ select * from t3; drop table if exists t1,t2,t3,t4; # -# Test-case for Bug #2397 RENAME TABLES is not blocked by -# FLUSH TABLES WITH READ LOCK +# Bug #2397 RENAME TABLES is not blocked by +# FLUSH TABLES WITH READ LOCK # connect (con1,localhost,root,,); @@ -58,10 +58,14 @@ FLUSH TABLES WITH READ LOCK; connection con1; send RENAME TABLE t1 TO t2, t3 to t4; connection con2; -sleep 1; show tables; UNLOCK TABLES; -sleep 1; + +# Wait for the the tables to be renamed +# i.e the query below succeds +let $query= select * from t2, t4; +source include/wait_for_query_to_suceed.inc; + show tables; drop table t2, t4; From 23061beb737204c79ba4027f354a9afe4aa93a3c Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Oct 2006 09:26:16 +0100 Subject: [PATCH 227/235] Bug#22828 _my_b_read() ignores return values for my_seek() calls - Because my_seek actually is capable of returning an error code we should exploit that in the best possible way. - There might be kernel errors or other errors we can't predict and capturing the return value of all system calls gives us better understanding of possible errors. mysys/mf_iocache.c: - Added check on return value for my_seek - Added comments mysys/my_chsize.c: - Added check on return value for my_seek - Added comments mysys/my_lock.c: - Added check on return value for my_seek - Added comments mysys/my_seek.c: - Added comments --- mysys/mf_iocache.c | 102 +++++++++++++++++++++++++++++++++++++++------ mysys/my_chsize.c | 6 ++- mysys/my_lock.c | 39 ++++++++++++++--- mysys/my_seek.c | 26 +++++++++++- 4 files changed, 153 insertions(+), 20 deletions(-) diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 0007784c2b2..709a3250f39 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -440,11 +440,24 @@ int _my_b_read(register IO_CACHE *info, byte *Buffer, uint Count) /* pos_in_file always point on where info->buffer was read */ pos_in_file=info->pos_in_file+(uint) (info->read_end - info->buffer); + + /* + Whenever a function which operates on IO_CACHE flushes/writes + some part of the IO_CACHE to disk it will set the property + "seek_not_done" to indicate this to other functions operating + on the IO_CACHE. + */ if (info->seek_not_done) - { /* File touched, do seek */ - VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0))); + { + if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) + == MY_FILEPOS_ERROR) + { + info->error= -1; + DBUG_RETURN(1); + } info->seek_not_done=0; } + diff_length=(uint) (pos_in_file & (IO_SIZE-1)); if (Count >= (uint) (IO_SIZE+(IO_SIZE-diff_length))) { /* Fill first intern buffer */ @@ -633,8 +646,22 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count) if (lock_io_cache(info, pos_in_file)) { info->share->active=info; - if (info->seek_not_done) /* File touched, do seek */ - VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0))); + /* + Whenever a function which operates on IO_CACHE flushes/writes + some part of the IO_CACHE to disk it will set the property + "seek_not_done" to indicate this to other functions operating + on the IO_CACHE. + */ + if (info->seek_not_done) + { + if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) + == MY_FILEPOS_ERROR) + { + info->error= -1; + unlock_io_cache(info); + DBUG_RETURN(1); + } + } len=(int)my_read(info->file,info->buffer, length, info->myflags); info->read_end=info->buffer + (len == -1 ? 0 : len); info->error=(len == (int)length ? 0 : len); @@ -668,11 +695,16 @@ int _my_b_read_r(register IO_CACHE *info, byte *Buffer, uint Count) /* - Do sequential read from the SEQ_READ_APPEND cache - we do this in three stages: + Do sequential read from the SEQ_READ_APPEND cache. + + We do this in three stages: - first read from info->buffer - then if there are still data to read, try the file descriptor - afterwards, if there are still data to read, try append buffer + + RETURNS + 0 Success + 1 Failed to read */ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count) @@ -700,7 +732,13 @@ int _my_b_seq_read(register IO_CACHE *info, byte *Buffer, uint Count) With read-append cache we must always do a seek before we read, because the write could have moved the file pointer astray */ - VOID(my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0))); + if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) + == MY_FILEPOS_ERROR) + { + info->error= -1; + unlock_append_buffer(info); + return (1); + } info->seek_not_done=0; diff_length=(uint) (pos_in_file & (IO_SIZE-1)); @@ -816,6 +854,21 @@ read_append_buffer: #ifdef HAVE_AIOWAIT +/* + Read from the IO_CACHE into a buffer and feed asynchronously + from disk when needed. + + SYNOPSIS + _my_b_async_read() + info IO_CACHE pointer + Buffer Buffer to retrieve count bytes from file + Count Number of bytes to read into Buffer + + RETURN VALUE + -1 An error has occurred; my_errno is set. + 0 Success + 1 An error has occurred; IO_CACHE to error state. +*/ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count) { uint length,read_length,diff_length,left_length,use_length,org_Count; @@ -906,13 +959,20 @@ int _my_b_async_read(register IO_CACHE *info, byte *Buffer, uint Count) info->error=(int) (read_length+left_length); return 1; } - VOID(my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0))); + + if (my_seek(info->file,next_pos_in_file,MY_SEEK_SET,MYF(0)) + == MY_FILEPOS_ERROR) + { + info->error= -1; + return (1); + } + read_length=IO_SIZE*2- (uint) (next_pos_in_file & (IO_SIZE-1)); if (Count < read_length) { /* Small block, read to cache */ if ((read_length=my_read(info->file,info->request_pos, read_length, info->myflags)) == (uint) -1) - return info->error= -1; + return info->error= -1; use_length=min(Count,read_length); memcpy(Buffer,info->request_pos,(size_t) use_length); info->read_pos=info->request_pos+Count; @@ -999,7 +1059,15 @@ int _my_b_get(IO_CACHE *info) return (int) (uchar) buff; } - /* Returns != 0 if error on write */ +/* + Write a byte buffer to IO_CACHE and flush to disk + if IO_CACHE is full. + + RETURN VALUE + 1 On error on write + 0 On success + -1 On error; my_errno contains error code. +*/ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count) { @@ -1022,8 +1090,18 @@ int _my_b_write(register IO_CACHE *info, const byte *Buffer, uint Count) { /* Fill first intern buffer */ length=Count & (uint) ~(IO_SIZE-1); if (info->seek_not_done) - { /* File touched, do seek */ - VOID(my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0))); + { + /* + Whenever a function which operates on IO_CACHE flushes/writes + some part of the IO_CACHE to disk it will set the property + "seek_not_done" to indicate this to other functions operating + on the IO_CACHE. + */ + if (my_seek(info->file,info->pos_in_file,MY_SEEK_SET,MYF(0))) + { + info->error= -1; + return (1); + } info->seek_not_done=0; } if (my_write(info->file,Buffer,(uint) length,info->myflags | MY_NABP)) diff --git a/mysys/my_chsize.c b/mysys/my_chsize.c index cf26428d65f..b925b52ac03 100644 --- a/mysys/my_chsize.c +++ b/mysys/my_chsize.c @@ -88,7 +88,11 @@ int my_chsize(File fd, my_off_t newlength, int filler, myf MyFlags) Fill space between requested length and true length with 'filler' We should never come here on any modern machine */ - VOID(my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE))); + if (my_seek(fd, newlength, MY_SEEK_SET, MYF(MY_WME+MY_FAE)) + == MY_FILEPOS_ERROR) + { + goto err; + } swap_variables(my_off_t, newlength, oldsize); } #endif diff --git a/mysys/my_lock.c b/mysys/my_lock.c index 8f915d6003a..c9641f46f5c 100644 --- a/mysys/my_lock.c +++ b/mysys/my_lock.c @@ -35,7 +35,14 @@ #include #endif - /* Lock a part of a file */ +/* + Lock a part of a file + + RETURN VALUE + 0 Success + -1 An error has occured and 'my_errno' is set + to indicate the actual error code. +*/ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, myf MyFlags) @@ -104,10 +111,22 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, #elif defined(HAVE_LOCKING) /* Windows */ { - my_bool error; + my_bool error= false; pthread_mutex_lock(&my_file_info[fd].mutex); - if (MyFlags & MY_SEEK_NOT_DONE) - VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))); + if (MyFlags & MY_SEEK_NOT_DONE) + { + if( my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)) + == MY_FILEPOS_ERROR ) + { + /* + If my_seek fails my_errno will already contain an error code; + just unlock and return error code. + */ + DBUG_PRINT("error",("my_errno: %d (%d)",my_errno,errno)); + pthread_mutex_unlock(&my_file_info[fd].mutex); + DBUG_RETURN(-1); + } + } error= locking(fd,locktype,(ulong) length) && errno != EINVAL; pthread_mutex_unlock(&my_file_info[fd].mutex); if (!error) @@ -145,7 +164,17 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, } #else if (MyFlags & MY_SEEK_NOT_DONE) - VOID(my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE))); + { + if (my_seek(fd,start,MY_SEEK_SET,MYF(MyFlags & ~MY_SEEK_NOT_DONE)) + == MY_FILEPOS_ERROR) + { + /* + If an error has occured in my_seek then we will already + have an error code in my_errno; Just return error code. + */ + DBUG_RETURN(-1); + } + } if (lockf(fd,locktype,length) != -1) DBUG_RETURN(0); #endif /* HAVE_FCNTL */ diff --git a/mysys/my_seek.c b/mysys/my_seek.c index 6af65d70fd0..a9ae68cd5f0 100644 --- a/mysys/my_seek.c +++ b/mysys/my_seek.c @@ -16,8 +16,30 @@ #include "mysys_priv.h" - /* Seek to position in file */ - /*ARGSUSED*/ +/* + Seek to a position in a file. + + ARGUMENTS + File fd The file descriptor + my_off_t pos The expected position (absolute or relative) + int whence A direction parameter and one of + {SEEK_SET, SEEK_CUR, SEEK_END} + myf MyFlags Not used. + + DESCRIPTION + The my_seek function is a wrapper around the system call lseek and + repositions the offset of the file descriptor fd to the argument + offset according to the directive whence as follows: + SEEK_SET The offset is set to offset bytes. + SEEK_CUR The offset is set to its current location plus offset bytes + SEEK_END The offset is set to the size of the file plus offset bytes + + RETURN VALUE + my_off_t newpos The new position in the file. + MY_FILEPOS_ERROR An error was encountered while performing + the seek. my_errno is set to indicate the + actual error. +*/ my_off_t my_seek(File fd, my_off_t pos, int whence, myf MyFlags __attribute__((unused))) From c54f778e96f3f72da109b059c6d1c2c9ef3aa368 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Oct 2006 17:16:07 +0100 Subject: [PATCH 228/235] Remove warning, exe_mysql_fix_system_tables are not available on windows --- mysql-test/mysql-test-run.pl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3e25d6e933c..de2498a7246 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -1801,14 +1801,16 @@ sub environment_setup () { # ---------------------------------------------------- # Setup env so childs can execute mysql_fix_system_tables # ---------------------------------------------------- - my $cmdline_mysql_fix_system_tables= - "$exe_mysql_fix_system_tables --no-defaults --host=localhost " . - "--user=root --password= " . - "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . - "--port=$master->[0]->{'port'} " . - "--socket=$master->[0]->{'path_sock'}"; - - $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; + if ( ! $glob_win32 ) + { + my $cmdline_mysql_fix_system_tables= + "$exe_mysql_fix_system_tables --no-defaults --host=localhost " . + "--user=root --password= " . + "--basedir=$glob_basedir --bindir=$path_client_bindir --verbose " . + "--port=$master->[0]->{'port'} " . + "--socket=$master->[0]->{'path_sock'}"; + $ENV{'MYSQL_FIX_SYSTEM_TABLES'}= $cmdline_mysql_fix_system_tables; + } # ---------------------------------------------------- # Setup env so childs can execute my_print_defaults From 8e0113be8c2266773d58e1709abdb3352c40057a Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Oct 2006 18:51:23 +0100 Subject: [PATCH 229/235] Make variables static to please Netware compiler client/mysqltest.c: Make the variables that are referenced from the "command_arg" arrays static to please the NetWare compiler. Apparently the arrays can't reference local stack variables. --- client/mysqltest.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/client/mysqltest.c b/client/mysqltest.c index 9f41586afae..7c1ce19283f 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -1409,7 +1409,7 @@ int open_file(const char *name) void do_source(struct st_command *command) { - DYNAMIC_STRING ds_filename; + static DYNAMIC_STRING ds_filename; const struct command_arg source_args[] = { "filename", ARG_STRING, TRUE, &ds_filename, "File to source" }; @@ -1697,7 +1697,7 @@ void do_system(struct st_command *command) void do_remove_file(struct st_command *command) { int error; - DYNAMIC_STRING ds_filename; + static DYNAMIC_STRING ds_filename; const struct command_arg rm_args[] = { "filename", ARG_STRING, TRUE, &ds_filename, "File to delete" }; @@ -1730,8 +1730,8 @@ void do_remove_file(struct st_command *command) void do_copy_file(struct st_command *command) { int error; - DYNAMIC_STRING ds_from_file; - DYNAMIC_STRING ds_to_file; + static DYNAMIC_STRING ds_from_file; + static DYNAMIC_STRING ds_to_file; const struct command_arg copy_file_args[] = { "from_file", ARG_STRING, TRUE, &ds_from_file, "Filename to copy from", "to_file", ARG_STRING, TRUE, &ds_to_file, "Filename to copy to" @@ -1766,7 +1766,7 @@ void do_copy_file(struct st_command *command) void do_file_exist(struct st_command *command) { int error; - DYNAMIC_STRING ds_filename; + static DYNAMIC_STRING ds_filename; const struct command_arg file_exist_args[] = { "filename", ARG_STRING, TRUE, &ds_filename, "File to check if it exist" }; @@ -1873,9 +1873,9 @@ void read_until_delimiter(DYNAMIC_STRING *ds, void do_write_file(struct st_command *command) { - DYNAMIC_STRING ds_content; - DYNAMIC_STRING ds_filename; - DYNAMIC_STRING ds_delimiter; + static DYNAMIC_STRING ds_content; + static DYNAMIC_STRING ds_filename; + static DYNAMIC_STRING ds_delimiter; const struct command_arg write_file_args[] = { "filename", ARG_STRING, TRUE, &ds_filename, "File to write to", "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" @@ -1927,8 +1927,8 @@ void do_perl(struct st_command *command) int error; char buf[FN_REFLEN]; FILE *res_file; - DYNAMIC_STRING ds_script; - DYNAMIC_STRING ds_delimiter; + static DYNAMIC_STRING ds_script; + static DYNAMIC_STRING ds_delimiter; const struct command_arg perl_args[] = { "delimiter", ARG_STRING, FALSE, &ds_delimiter, "Delimiter to read until" }; @@ -2985,14 +2985,14 @@ void do_connect(struct st_command *command) bool con_ssl= 0, con_compress= 0; char *ptr; - DYNAMIC_STRING ds_connection_name; - DYNAMIC_STRING ds_host; - DYNAMIC_STRING ds_user; - DYNAMIC_STRING ds_password; - DYNAMIC_STRING ds_database; - DYNAMIC_STRING ds_port; - DYNAMIC_STRING ds_sock; - DYNAMIC_STRING ds_options; + static DYNAMIC_STRING ds_connection_name; + static DYNAMIC_STRING ds_host; + static DYNAMIC_STRING ds_user; + static DYNAMIC_STRING ds_password; + static DYNAMIC_STRING ds_database; + static DYNAMIC_STRING ds_port; + static DYNAMIC_STRING ds_sock; + static DYNAMIC_STRING ds_options; const struct command_arg connect_args[] = { "connection name", ARG_STRING, TRUE, &ds_connection_name, "Name of the connection", From aa8c830d9b0a24b54c87a0300dde1e72e64cf0a9 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 31 Oct 2006 19:02:33 +0100 Subject: [PATCH 230/235] Improve the reading of .pid files from var/run - Only read *.pid - Only allow it to contain a number mysql-test/lib/mtr_io.pl: Check that the value read from pidfile is a valid number consisting only of digits mysql-test/lib/mtr_process.pl: Only process .pid files in var/run dir and print a warning if other files are found there. --- mysql-test/lib/mtr_io.pl | 12 +++++------ mysql-test/lib/mtr_process.pl | 40 ++++++++++++++++++++++------------- 2 files changed, 30 insertions(+), 22 deletions(-) diff --git a/mysql-test/lib/mtr_io.pl b/mysql-test/lib/mtr_io.pl index a1d7ffe87d8..984d834486c 100644 --- a/mysql-test/lib/mtr_io.pl +++ b/mysql-test/lib/mtr_io.pl @@ -37,18 +37,16 @@ sub mtr_get_pid_from_file ($) { open(FILE, '<', $pid_file_path) or mtr_error("can't open file \"$pid_file_path\": $!"); + # Read pid number from file my $pid= ; - - chomp($pid) if defined $pid; - close FILE; - return $pid if defined $pid && $pid ne ''; + return $pid if $pid=~ /^(\d+)/; - mtr_debug("Pid file '$pid_file_path' is empty. " . - "Sleeping $timeout second(s)..."); + mtr_debug("Pid file '$pid_file_path' does not yet contain pid number.\n" . + "Sleeping $timeout second(s) more..."); - sleep(1); + sleep($timeout); } mtr_error("Pid file '$pid_file_path' is corrupted. " . diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index affe8278376..048c336f8a3 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -438,25 +438,35 @@ sub mtr_kill_leftovers () { while ( my $elem= readdir(RUNDIR) ) { - my $pidfile= "$rundir/$elem"; - - if ( -f $pidfile ) + # Only read pid from files that end with .pid + if ( $elem =~ /.*[.]pid$/) { - mtr_debug("Processing PID file: '$pidfile'..."); - my $pid= mtr_get_pid_from_file($pidfile); + my $pidfile= "$rundir/$elem"; - mtr_debug("Got pid: $pid from file '$pidfile'"); + if ( -f $pidfile ) + { + mtr_debug("Processing PID file: '$pidfile'..."); - if ( $::glob_cygwin_perl or kill(0, $pid) ) - { - mtr_debug("There is process with pid $pid -- scheduling for kill."); - push(@pids, $pid); # We know (cygwin guess) it exists - } - else - { - mtr_debug("There is no process with pid $pid -- skipping."); - } + my $pid= mtr_get_pid_from_file($pidfile); + + mtr_debug("Got pid: $pid from file '$pidfile'"); + + if ( $::glob_cygwin_perl or kill(0, $pid) ) + { + mtr_debug("There is process with pid $pid -- scheduling for kill."); + push(@pids, $pid); # We know (cygwin guess) it exists + } + else + { + mtr_debug("There is no process with pid $pid -- skipping."); + } + } + } + else + { + mtr_warning("Found non pid file $elem in $rundir"); + next; } } closedir(RUNDIR); From b96f1a477d143dcba5f5d81813c2445c4de345a2 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Nov 2006 14:32:00 +0400 Subject: [PATCH 231/235] Fix for bug #22913: mysql --quick doesn't report some errors. We don't check for errors that may occur during data printing. client/mysql.cc: Fix for bug #22913: mysql --quick doesn't report some errors. - check for errors after the data output. --- client/mysql.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/mysql.cc b/client/mysql.cc index 2f9031b84b8..fcdd63b31e6 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1988,6 +1988,8 @@ com_go(String *buffer,char *line __attribute__((unused))) (long) mysql_num_rows(result), (long) mysql_num_rows(result) == 1 ? "row" : "rows"); end_pager(); + if (mysql_errno(&mysql)) + error= put_error(&mysql); } } else if (mysql_affected_rows(&mysql) == ~(ulonglong) 0) From 814926e453cc49dc869dbd2a9614dc9c51a96c04 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Nov 2006 11:55:41 +0100 Subject: [PATCH 232/235] Bug#22828 complementary patch: - 'false' not defined in C, use FALSE instead. mysys/my_lock.c: Fixed error for windows built: 'false' not defined in C, use FALSE instead. --- mysys/my_lock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysys/my_lock.c b/mysys/my_lock.c index ac91b6ce0ca..e32807004e8 100644 --- a/mysys/my_lock.c +++ b/mysys/my_lock.c @@ -101,7 +101,7 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, #elif defined(HAVE_LOCKING) /* Windows */ { - my_bool error= false; + my_bool error= FALSE; pthread_mutex_lock(&my_file_info[fd].mutex); if (MyFlags & MY_SEEK_NOT_DONE) { From ef128eb9d81f256883e9dd6e615c08fedeb5dcad Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Nov 2006 17:11:53 +0400 Subject: [PATCH 233/235] Fix for bug #23762: partition.test fails (partition_hash, partition_pruning as well) When partition pruning is used we have to initialize key_part->flag in the create_partition_index_descr() as it's checked in the get_mm_leaf(). sql/opt_range.cc: Fix for bug #23762: partition.test fails (partition_hash, partition_pruning as well) - set key_part->flag to 0. sql/opt_range.h: Fix for bug #23762: partition.test fails (partition_hash, partition_pruning as well) - comment added. --- sql/opt_range.cc | 5 +++++ sql/opt_range.h | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 4b7d65c8ae7..79b3e023a5f 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -3237,6 +3237,11 @@ static bool create_partition_index_description(PART_PRUNE_PARAM *ppar) key_part->field= (*field); key_part->image_type = Field::itRAW; + /* + We set keypart flag to 0 here as the only HA_PART_KEY_SEG is checked + in the RangeAnalysisModule. + */ + key_part->flag= 0; /* We don't set key_parts->null_bit as it will not be used */ ppar->is_part_keypart[part]= !in_subpart_fields; diff --git a/sql/opt_range.h b/sql/opt_range.h index 6f9c053cda2..170766c7c10 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -26,7 +26,9 @@ typedef struct st_key_part { uint16 key,part, store_length, length; - uint8 null_bit, flag; + uint8 null_bit; + /* Keypart flags (0 if partition pruning is used) */ + uint8 flag; Field *field; Field::imagetype image_type; } KEY_PART; From e3840255f7b3bbd2419fd435a5b53251ab3f6265 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Nov 2006 14:26:54 -0500 Subject: [PATCH 234/235] Fixed misuse of automake _DEPENDENCIES item. It caused Make try to create a bogus dependency "-lz" . sql/Makefile.am: automake "_DEPENDENCIES" names seem only to strip out compiler flags when it's automatically created. Manually written dependencies must be clean. --- sql/Makefile.am | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sql/Makefile.am b/sql/Makefile.am index 38a99aaef88..4781c1d675d 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -30,12 +30,13 @@ libexec_PROGRAMS = mysqld EXTRA_PROGRAMS = gen_lex_hash bin_PROGRAMS = mysql_tzinfo_to_sql gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ -LDADD = $(top_builddir)/vio/libvio.a \ +SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ $(top_builddir)/regex/libregex.a \ - $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ -mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(LDADD) + $(top_builddir)/strings/libmystrings.a +mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) +LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @pstack_libs@ \ @mysql_plugin_libs@ \ From 8e6b1e384933e0ce238f131b356379be58a55480 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Nov 2006 15:05:20 -0500 Subject: [PATCH 235/235] Bug#23865 mysql-test-run.pl on Windows only supports debug and release configurations Visual Studio builds each configuration in a different sub-directory. Only the sub- directories for release and debug are currently searched. mysql-test/lib/mtr_misc.pl: Bug#23865 mysql-test-run.pl on Windows only supports debug and release configurations - Added usage comments. mysql-test/mysql-test-run.pl: Bug#23865 mysql-test-run.pl on Windows only supports debug and release configurations - Moved Initial_Setup function to the command_line_setup function. - Defined new argument vs-config which can be used to inidicate the VS Configuration used to create the test executables. Argument can also be controlled with MTR_VS_CONFIG environment variable. --- mysql-test/lib/mtr_misc.pl | 15 +++ mysql-test/mysql-test-run.pl | 214 +++++++++++++++++++---------------- 2 files changed, 129 insertions(+), 100 deletions(-) diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index 5ac89aee62c..c016f3dc34f 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -66,6 +66,9 @@ sub mtr_add_arg ($$@) { ############################################################################## +# Note - More specific paths should be given before less specific. For examle +# /client/debug should be listed before /client + sub mtr_path_exists (@) { foreach my $path ( @_ ) { @@ -81,6 +84,9 @@ sub mtr_path_exists (@) { } } +# Note - More specific paths should be given before less specific. For examle +# /client/debug should be listed before /client + sub mtr_script_exists (@) { foreach my $path ( @_ ) { @@ -103,6 +109,9 @@ sub mtr_script_exists (@) { } } +# Note - More specific paths should be given before less specific. For examle +# /client/debug should be listed before /client + sub mtr_file_exists (@) { foreach my $path ( @_ ) { @@ -111,6 +120,9 @@ sub mtr_file_exists (@) { return ""; } +# Note - More specific paths should be given before less specific. For examle +# /client/debug should be listed before /client + sub mtr_exe_maybe_exists (@) { my @path= @_; @@ -129,6 +141,9 @@ sub mtr_exe_maybe_exists (@) { return ""; } +# Note - More specific paths should be given before less specific. For examle +# /client/debug should be listed before /client + sub mtr_exe_exists (@) { my @path= @_; if (my $path= mtr_exe_maybe_exists(@path)) diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 3e25d6e933c..1165877a883 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -68,6 +68,9 @@ use strict; use warnings; use diagnostics; +select(STDOUT); +$| = 1; # Automatically flush STDOUT + our $glob_win32_perl= ($^O eq "MSWin32"); # ActiveState Win32 Perl our $glob_cygwin_perl= ($^O eq "cygwin"); # Cygwin Perl our $glob_win32= ($glob_win32_perl or $glob_cygwin_perl); @@ -127,6 +130,12 @@ our $opt_vardir; # A path but set directly on cmd line our $path_vardir_trace; # unix formatted opt_vardir for trace files our $opt_tmpdir; # A path but set directly on cmd line +# Visual Studio produces executables in different sub-directories based on the +# configuration used to build them. To make life easier, an environment +# variable or command-line option may be specified to control which set of +# executables will be used by the test suite. +our $opt_vs_config = $ENV{'MTR_VS_CONFIG'}; + our $default_vardir; our $opt_usage; @@ -351,7 +360,6 @@ main(); sub main () { - initial_setup(); command_line_setup(); check_ndbcluster_support(\%mysqld_variables); @@ -433,86 +441,6 @@ sub main () { mtr_exit(0); } -############################################################################## -# -# Initial setup independent on command line arguments -# -############################################################################## - -sub initial_setup () { - - select(STDOUT); - $| = 1; # Make unbuffered - - $glob_scriptname= basename($0); - - # We require that we are in the "mysql-test" directory - # to run mysql-test-run - if (! -f $glob_scriptname) - { - mtr_error("Can't find the location for the mysql-test-run script\n" . - "Go to to the mysql-test directory and execute the script " . - "as follows:\n./$glob_scriptname"); - } - - if ( -d "../sql" ) - { - $opt_source_dist= 1; - } - - $glob_hostname= mtr_short_hostname(); - - # 'basedir' is always parent of "mysql-test" directory - $glob_mysql_test_dir= cwd(); - if ( $glob_cygwin_perl ) - { - # Windows programs like 'mysqld' needs Windows paths - $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`; - chomp($glob_mysql_test_dir); - } - $glob_basedir= dirname($glob_mysql_test_dir); - - # Expect mysql-bench to be located adjacent to the source tree, by default - $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench" - unless defined $glob_mysql_bench_dir; - - $path_my_basedir= - $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; - - $glob_timers= mtr_init_timers(); - - # - # Find the mysqld executable to be able to find the mysqld version - # number as early as possible - # - - # Look for the path where to find the client binaries - $path_client_bindir= mtr_path_exists("$glob_basedir/client_release", - "$glob_basedir/client_debug", - "$glob_basedir/client/release", - "$glob_basedir/client/debug", - "$glob_basedir/client", - "$glob_basedir/bin"); - - # Look for the mysqld executable - $exe_mysqld= mtr_exe_exists ("$glob_basedir/sql/mysqld", - "$path_client_bindir/mysqld-max-nt", - "$path_client_bindir/mysqld-max", - "$path_client_bindir/mysqld-nt", - "$path_client_bindir/mysqld", - "$path_client_bindir/mysqld-debug", - "$path_client_bindir/mysqld-max", - "$glob_basedir/libexec/mysqld", - "$glob_basedir/bin/mysqld", - "$glob_basedir/sql/release/mysqld", - "$glob_basedir/sql/debug/mysqld"); - - # Use the mysqld found above to find out what features are available - collect_mysqld_features(); - -} - - ############################################################################## # @@ -590,6 +518,7 @@ sub command_line_setup () { 'bench' => \$opt_bench, 'small-bench' => \$opt_small_bench, 'with-ndbcluster' => \$opt_with_ndbcluster, + 'vs-config' => \$opt_vs_config, # Control what test suites or cases to run 'force' => \$opt_force, @@ -695,6 +624,68 @@ sub command_line_setup () { usage("") if $opt_usage; + $glob_scriptname= basename($0); + + # We require that we are in the "mysql-test" directory + # to run mysql-test-run + if (! -f $glob_scriptname) + { + mtr_error("Can't find the location for the mysql-test-run script\n" . + "Go to to the mysql-test directory and execute the script " . + "as follows:\n./$glob_scriptname"); + } + + if ( -d "../sql" ) + { + $opt_source_dist= 1; + } + + $glob_hostname= mtr_short_hostname(); + + # 'basedir' is always parent of "mysql-test" directory + $glob_mysql_test_dir= cwd(); + if ( $glob_cygwin_perl ) + { + # Windows programs like 'mysqld' needs Windows paths + $glob_mysql_test_dir= `cygpath -m "$glob_mysql_test_dir"`; + chomp($glob_mysql_test_dir); + } + $glob_basedir= dirname($glob_mysql_test_dir); + + # Expect mysql-bench to be located adjacent to the source tree, by default + $glob_mysql_bench_dir= "$glob_basedir/../mysql-bench" + unless defined $glob_mysql_bench_dir; + + $path_my_basedir= + $opt_source_dist ? $glob_mysql_test_dir : $glob_basedir; + + $glob_timers= mtr_init_timers(); + + # + # Find the mysqld executable to be able to find the mysqld version + # number as early as possible + # + + # Look for the client binaries + $path_client_bindir= mtr_path_exists(vs_config_dirs('client', ''), + "$glob_basedir/client_release", + "$glob_basedir/client_debug", + "$glob_basedir/client"); + + $exe_mysqld= mtr_exe_exists (vs_config_dirs('sql', 'mysqld'), + "$glob_basedir/sql/mysqld", + "$path_client_bindir/mysqld-max-nt", + "$path_client_bindir/mysqld-max", + "$path_client_bindir/mysqld-nt", + "$path_client_bindir/mysqld", + "$path_client_bindir/mysqld-debug", + "$path_client_bindir/mysqld-max", + "$glob_basedir/libexec/mysqld", + "$glob_basedir/bin/mysqld"); + + # Use the mysqld found above to find out what features are available + collect_mysqld_features(); + if ( $opt_comment ) { print "\n"; @@ -1396,16 +1387,14 @@ sub executable_setup () { # Look for my_print_defaults $exe_my_print_defaults= - mtr_exe_exists("$path_client_bindir/my_print_defaults", - "$glob_basedir/extra/my_print_defaults", - "$glob_basedir/extra/release/my_print_defaults", - "$glob_basedir/extra/debug/my_print_defaults"); + mtr_exe_exists(vs_config_dirs('extra', 'my_print_defaults'), + "$path_client_bindir/my_print_defaults", + "$glob_basedir/extra/my_print_defaults"); # Look for perror - $exe_perror= mtr_exe_exists("$glob_basedir/extra/perror", - "$path_client_bindir/perror", - "$glob_basedir/extra/release/perror", - "$glob_basedir/extra/debug/perror"); + $exe_perror= mtr_exe_exists(vs_config_dirs('extra', 'perror'), + "$glob_basedir/extra/perror", + "$path_client_bindir/perror"); # Look for the client binaries $exe_mysqlcheck= mtr_exe_exists("$path_client_bindir/mysqlcheck"); @@ -1451,22 +1440,20 @@ sub executable_setup () { # Look for the udf_example library $lib_udf_example= - mtr_file_exists("$glob_basedir/sql/.libs/udf_example.so", - "$glob_basedir/sql/release/udf_example.dll", - "$glob_basedir/sql/debug/udf_example.dll"); + mtr_file_exists(vs_config_dirs('sql', 'udf_example.dll'), + "$glob_basedir/sql/.libs/udf_example.so",); # Look for mysqltest executable if ( $glob_use_embedded_server ) { $exe_mysqltest= - mtr_exe_exists("$glob_basedir/libmysqld/examples/mysqltest_embedded", - "$path_client_bindir/mysqltest_embedded"); + mtr_exe_exists(vs_config_dirs('libmysqld/examples', 'mysqltest_embedded'), + "$glob_basedir/libmysqld/examples/mysqltest_embedded", + "$path_client_bindir/mysqltest_embedded"); } else { $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); - - } # Look for mysql_client_test executable which may _not_ exist in @@ -1475,15 +1462,15 @@ sub executable_setup () { { $exe_mysql_client_test= mtr_exe_maybe_exists( + vs_config_dirs('libmysqld/examples', 'mysql_client_test_embedded'), "$glob_basedir/libmysqld/examples/mysql_client_test_embedded"); } else { $exe_mysql_client_test= - mtr_exe_maybe_exists("$glob_basedir/tests/mysql_client_test", - "$glob_basedir/tests/release/mysql_client_test", - "$glob_basedir/tests/debug/mysql_client_test", - "$glob_basedir/bin"); + mtr_exe_maybe_exists(vs_config_dirs('tests', 'mysql_client_test'), + "$glob_basedir/tests/mysql_client_test", + "$glob_basedir/bin"); } } @@ -2097,6 +2084,31 @@ sub check_debug_support ($) { $debug_compiled_binaries= 1; } +############################################################################## +# +# Helper function to handle configuration-based subdirectories which Visual +# Studio uses for storing binaries. If opt_vs_config is set, this returns +# a path based on that setting; if not, it returns paths for the default +# /release/ and /debug/ subdirectories. +# +# $exe can be undefined, if the directory itself will be used +# +############################################################################### + +sub vs_config_dirs ($$) { + my ($path_part, $exe) = @_; + + $exe = "" if not defined $exe; + + if ($opt_vs_config) + { + return ("$glob_basedir/$path_part/$opt_vs_config/$exe"); + } + + return ("$glob_basedir/$path_part/release/$exe", + "$glob_basedir/$path_part/debug/$exe"); +} + ############################################################################## # # Start the ndb cluster @@ -4616,6 +4628,8 @@ Options to control what engine/variation to run bench Run the benchmark suite small-bench Run the benchmarks with --small-tests --small-tables with-ndbcluster Use cluster as default table type for benchmark + vs-config Visual Studio configuration used to create executables + (default: MTR_VS_CONFIG environment variable) Options to control directories to use benchdir=DIR The directory where the benchmark suite is stored