From a4a48c09b659cfef129f7d8704a61d594d9b4e3a Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Fri, 28 Jul 2006 10:21:47 +0200 Subject: [PATCH 01/15] 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 56e5fd1b5f3822b0d21a8fbb746fca7aa9f6c1e6 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 12:33:59 +0200 Subject: [PATCH 02/15] Add missing semicolon in csv test --- 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 3d2e366be154a74294aace71ec300f53ef6f0f53 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 12:35:30 +0200 Subject: [PATCH 03/15] Add missing semicolon in query_cache test --- 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 dbd1e64aa237431f3b54b68bba9803d4504123fc Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 13:01:07 +0200 Subject: [PATCH 04/15] 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 b5d0d4af03bfb417a2c0e728f3368220dd78fb7b Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 13:02:28 +0200 Subject: [PATCH 05/15] 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 768a77d3c61c1e45fee57ac7b4df24931642c613 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 13:03:17 +0200 Subject: [PATCH 06/15] Add missing semicolon to wait_timeout test --- 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 a0e706adc9a79cf0ac5eefb21dc47bc267ad18b1 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 18:11:19 +0200 Subject: [PATCH 07/15] Add missing delimiter in subselect test --- 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 ffd4fd41aa2c28f994c5b35fc48f1c844fabd203 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 19:36:11 +0200 Subject: [PATCH 08/15] 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 1dd4ecaa0d29a94ab5989d9fa498846cf4990520 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sat, 29 Jul 2006 19:38:46 +0200 Subject: [PATCH 09/15] Change faulty delimiter ; to | and remove junk in result file caused by that --- 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 2711af3e9841b47c80c1fcdacd8de04459b582be Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sun, 30 Jul 2006 17:57:15 +0200 Subject: [PATCH 10/15] Improve and fix bugs in 'read_line' function of mysqltest --- 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 9408be5dc3b33a0559d8b354325485539438e428 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sun, 30 Jul 2006 18:00:08 +0200 Subject: [PATCH 11/15] Remove todo about better manual --- 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 df37f4f9ce4bbdfc36b125c1defe99e9b83b8dde Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sun, 30 Jul 2006 18:01:42 +0200 Subject: [PATCH 12/15] 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 98e3552a9ae3ac4c639a8598bc4e849cab67de34 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sun, 30 Jul 2006 18:21:31 +0200 Subject: [PATCH 13/15] Cleanup error messages in mysqltest --- 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 c274b518076813f74db7f308681a1a53b250c62c Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sun, 30 Jul 2006 19:16:51 +0200 Subject: [PATCH 14/15] Add new commands to mysqltest - to make it easier to write portable test scripts --- 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 5245254ba9b1e7a2774dbe3b7ab7696c224c69a4 Mon Sep 17 00:00:00 2001 From: "msvensson@shellback.(none)" <> Date: Sun, 30 Jul 2006 19:46:04 +0200 Subject: [PATCH 15/15] remove unneeded bugfix when read_line function in mysqltest has been fixed --- 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;