List:Commits« Previous MessageNext Message »
From:Magnus Svensson Date:August 8 2008 5:55pm
Subject:bzr commit into mysql-6.0 branch (msvensson:2699)
View as plain text  
#At file:///home/msvensson/mysql/6.0-rpl/

 2699 Magnus Svensson	2008-08-08 [merge]
      Merge
removed:
  mysql-test/r/not_as_root.require
renamed:
  client/mysqltest.c => client/mysqltest.cc
  mysql-test/include/analyze_failure_sync_with_master.test => mysql-test/include/analyze-sync_with_master.test
modified:
  client/CMakeLists.txt
  client/Makefile.am
  client/mysqladmin.cc
  libmysqld/examples/CMakeLists.txt
  libmysqld/examples/Makefile.am
  mysql-test/extra/rpl_tests/rpl_row_sp002.test
  mysql-test/include/mysqltest-x.inc
  mysql-test/include/not_as_root.inc
  mysql-test/lib/mtr_cases.pm
  mysql-test/lib/mtr_report.pm
  mysql-test/mysql-test-run.pl
  mysql-test/r/mysqltest.result
  mysql-test/t/execution_constants.test
  mysql-test/t/fix_priv_tables.test
  mysql-test/t/mysqltest.test
  mysql-test/t/openssl_1.test
  mysql-test/t/ps.test
  client/mysqltest.cc
  mysql-test/include/analyze-sync_with_master.test

=== modified file 'client/CMakeLists.txt'
--- a/client/CMakeLists.txt	2008-06-20 11:40:01 +0000
+++ b/client/CMakeLists.txt	2008-08-08 17:55:07 +0000
@@ -32,8 +32,8 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/
 ADD_EXECUTABLE(mysql completion_hash.cc mysql.cc readline.cc sql_string.cc ../mysys/my_conio.c)
 TARGET_LINK_LIBRARIES(mysql mysqlclient_notls ws2_32)
 
-ADD_EXECUTABLE(mysqltest mysqltest.c)
-SET_SOURCE_FILES_PROPERTIES(mysqltest.c PROPERTIES COMPILE_FLAGS "-DTHREADS")
+ADD_EXECUTABLE(mysqltest mysqltest.cc)
+SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS")
 TARGET_LINK_LIBRARIES(mysqltest mysqlclient mysys regex ws2_32 dbug)
 
 ADD_EXECUTABLE(mysqlcheck mysqlcheck.c)

=== modified file 'client/Makefile.am'
--- a/client/Makefile.am	2008-06-20 11:40:01 +0000
+++ b/client/Makefile.am	2008-08-08 17:55:07 +0000
@@ -86,8 +86,8 @@ mysqlslap_LDADD =		$(CXXLDFLAGS) $(CLIEN
 				$(LIBMYSQLCLIENT_LA) \
 				$(top_builddir)/mysys/libmysys.a
 
-mysqltest_SOURCES=		mysqltest.c
-mysqltest_CFLAGS=		-DTHREAD -UUNDEF_THREADS_HACK
+mysqltest_SOURCES=		mysqltest.cc
+mysqltest_CXXFLAGS=		-DTHREAD -UUNDEF_THREADS_HACK
 mysqltest_LDADD =		$(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
 				@CLIENT_EXTRA_LDFLAGS@ \
 				$(LIBMYSQLCLIENT_LA) \

=== modified file 'client/mysqladmin.cc'
--- a/client/mysqladmin.cc	2008-05-29 15:44:11 +0000
+++ b/client/mysqladmin.cc	2008-08-08 17:55:07 +0000
@@ -23,10 +23,6 @@
 #include <sys/stat.h>
 #include <mysql.h>
 
-#ifdef LATER_HAVE_NDBCLUSTER_DB
-#include "../ndb/src/mgmclient/ndb_mgmclient.h"
-#endif
-
 #define ADMIN_VERSION "8.42"
 #define MAX_MYSQL_VAR 256
 #define SHUTDOWN_DEF_TIMEOUT 3600		/* Wait for shutdown */
@@ -46,10 +42,6 @@ static uint tcp_port = 0, option_wait = 
 static uint opt_count_iterations= 0, my_end_arg;
 static ulong opt_connect_timeout, opt_shutdown_timeout;
 static char * unix_port=0;
-#ifdef LATER_HAVE_NDBCLUSTER_DB
-static my_bool opt_ndbcluster=0;
-static char *opt_ndb_connectstring=0;
-#endif
 
 #ifdef HAVE_SMEM
 static char *shared_memory_base_name=0;
@@ -105,9 +97,6 @@ enum commands {
   ADMIN_PING,             ADMIN_EXTENDED_STATUS, ADMIN_FLUSH_STATUS,
   ADMIN_FLUSH_PRIVILEGES, ADMIN_START_SLAVE,     ADMIN_STOP_SLAVE,
   ADMIN_FLUSH_THREADS,    ADMIN_OLD_PASSWORD
-#ifdef LATER_HAVE_NDBCLUSTER_DB
-  ,ADMIN_NDB_MGM
-#endif
 };
 static const char *command_names[]= {
   "create",               "drop",                "shutdown",
@@ -118,9 +107,6 @@ static const char *command_names[]= {
   "ping",                 "extended-status",     "flush-status",
   "flush-privileges",     "start-slave",         "stop-slave",
   "flush-threads","old-password",
-#ifdef LATER_HAVE_NDBCLUSTER_DB
-  "ndb-mgm",
-#endif
   NullS
 };
 
@@ -224,14 +210,6 @@ static struct my_option my_long_options[
   {"shutdown_timeout", OPT_SHUTDOWN_TIMEOUT, "", (uchar**) &opt_shutdown_timeout,
    (uchar**) &opt_shutdown_timeout, 0, GET_ULONG, REQUIRED_ARG,
    SHUTDOWN_DEF_TIMEOUT, 0, 3600*12, 0, 1, 0},
-#ifdef LATER_HAVE_NDBCLUSTER_DB
-  {"ndbcluster", OPT_NDBCLUSTER, ""
-   "", (uchar**) &opt_ndbcluster,
-   (uchar**) &opt_ndbcluster, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-  {"ndb-connectstring", OPT_NDB_CONNECTSTRING, ""
-   "", (uchar**) &opt_ndb_connectstring,
-   (uchar**) &opt_ndb_connectstring, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-#endif
   { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
 };
 
@@ -984,24 +962,6 @@ static int execute_commands(MYSQL *mysql
       }
       mysql->reconnect=1;	/* Automatic reconnect is default */
       break;
-#ifdef LATER_HAVE_NDBCLUSTER_DB
-    case ADMIN_NDB_MGM:
-    {
-      if (argc < 2)
-      {
-	my_printf_error(0, "Too few arguments to ndb-mgm", error_flags);
-	return 1;
-      }
-      {
-        Ndb_mgmclient_handle cmd=
-	  ndb_mgmclient_handle_create(opt_ndb_connectstring);
-        ndb_mgmclient_execute(cmd, --argc, ++argv);
-	ndb_mgmclient_handle_destroy(cmd);
-      }
-      argc= 0;
-    }
-    break;
-#endif
     default:
       my_printf_error(0, "Unknown command: '%-.60s'", error_flags, argv[0]);
       return 1;

=== renamed file 'client/mysqltest.c' => 'client/mysqltest.cc'
--- a/client/mysqltest.c	2008-08-07 20:51:09 +0000
+++ b/client/mysqltest.cc	2008-08-08 17:55:07 +0000
@@ -169,7 +169,6 @@ static ulonglong timer_start;
 static void timer_output(void);
 static ulonglong timer_now(void);
 
-static ulonglong progress_start= 0;
 
 static ulong connection_retry_sleep= 100000; /* Microseconds */
 
@@ -186,12 +185,12 @@ DYNAMIC_ARRAY q_lines;
 
 #include "sslopt-vars.h"
 
-struct
+struct Parser
 {
   int read_lines,current_line;
 } parser;
 
-struct
+struct MasterPos
 {
   char file[FN_REFLEN];
   ulong pos;
@@ -200,7 +199,7 @@ struct
 /* if set, all results are concated and compared against this file */
 const char *result_file_name= 0;
 
-typedef struct st_var
+typedef struct
 {
   char *name;
   int name_len;
@@ -422,7 +421,7 @@ struct st_command
 TYPELIB command_typelib= {array_elements(command_names),"",
 			  command_names, 0};
 
-DYNAMIC_STRING ds_res, ds_progress, ds_warning_messages;
+DYNAMIC_STRING ds_res;
 
 char builtin_echo[FN_REFLEN];
 
@@ -432,8 +431,6 @@ void abort_not_supported_test(const char
   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);
 void log_msg(const char *fmt, ...)
   ATTRIBUTE_FORMAT(printf, 1, 2);
 
@@ -445,9 +442,6 @@ VAR* var_get(const char *var_name, const
              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_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);
@@ -483,6 +477,168 @@ void free_all_replace(){
   free_replace_column();
 }
 
+class LogFile {
+  FILE* m_file;
+  char m_file_name[FN_REFLEN];
+  uint m_bytes_written;
+public:
+  LogFile() : m_file(NULL), m_bytes_written(0) {
+    bzero(m_file_name, sizeof(m_file_name));
+  }
+
+  ~LogFile() {
+    close();
+  }
+
+  const char* file_name() const { return m_file_name; }
+  uint bytes_written() const { return m_bytes_written; }
+
+  void open(const char* dir, const char* name, const char* ext)
+  {
+    DBUG_ENTER("LogFile::open");
+    DBUG_PRINT("enter", ("dir: %s, name: %s",
+                         name, dir));
+    if (!name)
+    {
+      m_file= stdout;
+      DBUG_VOID_RETURN;
+    }
+
+    fn_format(m_file_name, name, dir, ext,
+              *dir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
+              MY_REPLACE_EXT);
+
+    DBUG_PRINT("info", ("file_name: %s", m_file_name));
+
+    if ((m_file= fopen(m_file_name, "w+")) == NULL)
+      die("Failed to open log file %s, errno: %d", m_file_name, errno);
+
+    DBUG_VOID_RETURN;
+  }
+
+  void close()
+  {
+    if (m_file && m_file != stdout)
+      fclose(m_file);
+    m_file= NULL;
+  }
+
+  void flush()
+  {
+    if (m_file && m_file != stdout)
+      fflush(m_file);
+  }
+
+  void write(DYNAMIC_STRING* ds)
+  {
+    DBUG_ENTER("LogFile::write");
+    DBUG_ASSERT(m_file);
+
+    if (ds->length == 0)
+      DBUG_VOID_RETURN;
+    DBUG_ASSERT(ds->str);
+
+    if (fwrite(ds->str, 1, ds->length, m_file) != ds->length)
+      die("Failed to write %d bytes to '%s', errno: %d",
+          ds->length, m_file_name, errno);
+    m_bytes_written+= ds->length;
+    DBUG_VOID_RETURN;
+  }
+
+  void show_tail(uint lines) {
+    DBUG_ENTER("LogFile::show_tail");
+
+    if (!m_file || m_file == stdout)
+      DBUG_VOID_RETURN;
+
+    if (lines == 0)
+      DBUG_VOID_RETURN;
+    lines++;
+
+    int show_offset= 0;
+    char buf[256];
+    size_t bytes;
+    bool found_bof= false;
+
+    /* Search backward in file until "lines" newline has been found */
+    while (lines && !found_bof)
+    {
+      show_offset-= sizeof(buf);
+      while(fseek(m_file, show_offset, SEEK_END) != 0 && show_offset < 0)
+      {
+        found_bof= true;
+        // Seeking before start of file
+        show_offset++;
+      }
+
+      if ((bytes= fread(buf, 1, sizeof(buf), m_file)) <= 0)
+      {
+        fprintf(stderr, "Failed to read from '%s', errno: %d\n",
+                m_file_name, errno);
+        DBUG_VOID_RETURN;
+      }
+
+      DBUG_PRINT("info", ("Read %d bytes from file, buf: %s", bytes, buf));
+
+      char* show_from= buf + bytes;
+      while(show_from > buf && lines > 0 )
+      {
+        show_from--;
+        if (*show_from == '\n')
+          lines--;
+      }
+      if (show_from != buf)
+      {
+        // The last new line was found in this buf, adjust offset
+        show_offset+= (show_from - buf) + 1;
+        DBUG_PRINT("info", ("adjusted offset to %d", show_offset));
+      }
+      DBUG_PRINT("info", ("show_offset: %d", show_offset));
+    }
+
+    fprintf(stderr, "\nThe result from queries just before the failure was:\n");
+
+    DBUG_PRINT("info", ("show_offset: %d", show_offset));
+    if (!lines)
+    {
+      fprintf(stderr, "< snip >\n");
+
+      if (fseek(m_file, show_offset, SEEK_END) != 0)
+      {
+        fprintf(stderr, "Failed to seek to position %d in '%s', errno: %d",
+                show_offset, m_file_name, errno);
+        DBUG_VOID_RETURN;
+      }
+
+    }
+    else {
+      DBUG_PRINT("info", ("Showing the whole file"));
+      if (fseek(m_file, 0L, SEEK_SET) != 0)
+      {
+        fprintf(stderr, "Failed to seek to pos 0 in '%s', errno: %d",
+                m_file_name, errno);
+        DBUG_VOID_RETURN;
+      }
+    }
+
+    while ((bytes= fread(buf, 1, sizeof(buf), m_file)) > 0)
+      fwrite(buf, 1, bytes, stderr);
+
+    if (!lines)
+    {
+      fprintf(stderr,
+              "\nMore results from queries before failure can be found in %s\n",
+              m_file_name);
+    }
+    fflush(stderr);
+
+    DBUG_VOID_RETURN;
+  }
+};
+
+LogFile log_file;
+LogFile progress_file;
+
 void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
                                int len);
 void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
@@ -623,7 +779,7 @@ void do_eval(DYNAMIC_STRING *query_eval,
 
 
 /*
-  Run query and dump the result to stdout in vertical format
+  Run query and dump the result to stderr in vertical format
 
   NOTE! This function should be safe to call when an error
   has occured and thus any further errors will be ignored(although logged)
@@ -955,8 +1111,6 @@ void free_used_memory()
     my_free(embedded_server_args[--embedded_server_arg_count],MYF(0));
   delete_dynamic(&q_lines);
   dynstr_free(&ds_res);
-  dynstr_free(&ds_progress);
-  dynstr_free(&ds_warning_messages);
   free_all_replace();
   my_free(opt_pass,MYF(MY_ALLOW_ZERO_PTR));
   free_defaults(default_argv);
@@ -1034,31 +1188,7 @@ void die(const char *fmt, ...)
   fprintf(stderr, "\n");
   fflush(stderr);
 
-  /* Show results from queries just before failure */
-  if (ds_res.length && opt_tail_lines)
-  {
-    int tail_lines= opt_tail_lines;
-    char* show_from= ds_res.str + ds_res.length - 1;
-    while(show_from > ds_res.str && tail_lines > 0 )
-    {
-      show_from--;
-      if (*show_from == '\n')
-        tail_lines--;
-    }
-    fprintf(stderr, "\nThe result from queries just before the failure was:\n");
-    if (show_from > ds_res.str)
-      fprintf(stderr, "< snip >");
-    fprintf(stderr, "%s", show_from);
-    fflush(stderr);
-  }
-
-  /* Dump the result that has been accumulated so far to .log file */
-  if (result_file_name && ds_res.length)
-    dump_result_to_log_file(ds_res.str, ds_res.length);
-
-  /* Dump warning messages */
-  if (result_file_name && ds_warning_messages.length)
-    dump_warning_messages();
+  log_file.show_tail(opt_tail_lines);
 
   /*
     Help debugging by displaying any warnings that might have
@@ -1139,41 +1269,6 @@ 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)
-  {
-    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);
-  }
-
-  len= my_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;
-}
-
-
 void log_msg(const char *fmt, ...)
 {
   va_list args;
@@ -1582,18 +1677,17 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, c
 
 
 /*
-  Check the content of ds against result file
+  Check the content of log against result file
 
   SYNOPSIS
   check_result
-  ds - content to be checked
 
   RETURN VALUES
   error - the function will not return
 
 */
 
-void check_result(DYNAMIC_STRING* ds)
+void check_result()
 {
   const char* mess= "Result content mismatch\n";
 
@@ -1601,10 +1695,7 @@ void check_result(DYNAMIC_STRING* ds)
   DBUG_ASSERT(result_file_name);
   DBUG_PRINT("enter", ("result_file_name: %s", result_file_name));
 
-  if (access(result_file_name, F_OK) != 0)
-    die("The specified result file does not exist: '%s'", result_file_name);
-
-  switch (dyn_string_cmp(ds, result_file_name)) {
+  switch (compare_files(log_file.file_name(), result_file_name)) {
   case RESULT_OK:
     break; /* ok */
   case RESULT_LENGTH_MISMATCH:
@@ -1632,9 +1723,10 @@ void check_result(DYNAMIC_STRING* ds)
       fn_format(reject_file, result_file_name, opt_logdir,
                 ".reject", MY_REPLACE_DIR | MY_REPLACE_EXT);
     }
-    str_to_file(reject_file, ds->str, ds->length);
 
-    dynstr_set(ds, NULL); /* Don't create a .log file */
+    if (my_copy(log_file.file_name(), reject_file, MYF(0)) != 0)
+      die("Failed to copy '%s' to '%s', errno: %d",
+          log_file.file_name(), reject_file, errno);
 
     show_diff(NULL, result_file_name, reject_file);
     die(mess);
@@ -1748,7 +1840,7 @@ VAR *var_init(VAR *v, const char *name, 
   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))))
+  if (!(tmp_var->str_val = (char*)my_malloc(val_alloc_len+1, MYF(MY_WME))))
     die("Out of memory");
 
   memcpy(tmp_var->name, name, name_len);
@@ -2162,8 +2254,8 @@ void var_copy(VAR *dest, VAR *src)
   /* 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))))
+        ? (char*)my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME))
+        : (char*)my_malloc(src->alloced_len, MYF(MY_WME))))
     die("Out of memory");
   else
     dest->alloced_len= src->alloced_len;
@@ -2184,8 +2276,16 @@ void eval_expr(VAR *v, const char *p, co
   if (*p == '$')
   {
     VAR *vp;
+    const char* expected_end= *p_end; // Remember var end
     if ((vp= var_get(p, p_end, 0, 0)))
       var_copy(v, vp);
+
+    /* Make sure there was just a $variable and nothing else */
+    const char* end= *p_end + 1;
+    if (end < expected_end)
+      die("Found junk '%.*s' after $variable in expression",
+          expected_end - end - 1, end);
+
     DBUG_VOID_RETURN;
   }
 
@@ -2221,9 +2321,9 @@ void eval_expr(VAR *v, const char *p, co
       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))))
+            v->str_val ?
+            (char*)my_realloc(v->str_val, v->alloced_len+1, MYF(MY_WME)) :
+            (char*)my_malloc(v->alloced_len+1, MYF(MY_WME))))
         die("Out of memory");
     }
     v->str_val_len = new_val_len;
@@ -2266,7 +2366,7 @@ int open_file(const char *name)
   if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
   {
     cur_file--;
-    die("Could not open '%s' for reading", buff);
+    die("Could not open '%s' for reading, errno: %d", buff, errno);
   }
   cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
   cur_file->lineno=1;
@@ -2553,7 +2653,7 @@ enum enum_operator
   SYNOPSIS
   do_modify_var()
   query	called command
-  operator    operation to perform on the var
+  op    operation to perform on the var
 
   DESCRIPTION
   dec $var_name
@@ -2562,7 +2662,7 @@ enum enum_operator
 */
 
 int do_modify_var(struct st_command *command,
-                  enum enum_operator operator)
+                  enum enum_operator op)
 {
   const char *p= command->first_argument;
   VAR* v;
@@ -2572,7 +2672,7 @@ int do_modify_var(struct st_command *com
     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) {
+  switch (op) {
   case DO_DEC:
     v->int_val--;
     break;
@@ -3513,21 +3613,19 @@ void do_wait_for_slave_to_stop(struct st
 }
 
 
-void do_sync_with_master2(long offset)
+void do_sync_with_master2(struct st_command *command, long offset)
 {
   MYSQL_RES *res;
   MYSQL_ROW row;
   MYSQL *mysql= &cur_con->mysql;
   char query_buf[FN_REFLEN+128];
-  int tries= 0;
+  int timeout= 300; /* seconds */
 
   if (!master_pos.file[0])
     die("Calling 'sync_with_master' without calling 'save_master_pos'");
 
-  sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
-	  master_pos.pos + offset);
-
-wait_for_position:
+  sprintf(query_buf, "select master_pos_wait('%s', %ld, %d)",
+          master_pos.file, master_pos.pos + offset, timeout);
 
   if (mysql_query(mysql, query_buf))
     die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql),
@@ -3540,27 +3638,48 @@ wait_for_position:
     mysql_free_result(res);
     die("empty result in %s", query_buf);
   }
-  if (!row[0])
+
+  int result= -99;
+  const char* result_str= row[0];
+  if (result_str)
+    result= atoi(result_str);
+
+  mysql_free_result(res);
+
+  if (!result_str || result < 0)
   {
-    /*
-      It may be that the slave SQL thread has not started yet, though START
-      SLAVE has been issued ?
-    */
-    mysql_free_result(res);
-    if (tries++ == 30)
+    /* master_pos_wait returned NULL or < 0 */
+    show_query(mysql, "SHOW MASTER STATUS");
+    show_query(mysql, "SHOW SLAVE STATUS");
+    show_query(mysql, "SHOW PROCESSLIST");
+    fprintf(stderr, "analyze: sync_with_master\n");
+
+    if (!result_str)
     {
-      show_query(mysql, "SHOW MASTER STATUS");
-      show_query(mysql, "SHOW SLAVE STATUS");
-      die("could not sync with master ('%s' returned NULL)", query_buf);
+      /*
+        master_pos_wait returned NULL. This indicates that
+        slave SQL thread is not started, the slave's master
+        information is not initialized, the arguments are
+        incorrect, or an error has occured
+      */
+      die("%.*s failed: '%s' returned NULL "\
+          "indicating slave SQL thread failure",
+          command->first_word_len, command->query, query_buf);
+
     }
-    sleep(1); /* So at most we will wait 30 seconds and make 31 tries */
-    goto wait_for_position;
+
+    if (result == -1)
+      die("%.*s failed: '%s' returned -1 "\
+          "indicating timeout after %d seconds",
+          command->first_word_len, command->query, query_buf, timeout);
+    else
+      die("%.*s failed: '%s' returned unknown result :%d",
+          command->first_word_len, command->query, query_buf, result);
   }
-  mysql_free_result(res);
+
   return;
 }
 
-
 void do_sync_with_master(struct st_command *command)
 {
   long offset= 0;
@@ -3575,7 +3694,7 @@ void do_sync_with_master(struct st_comma
       die("Invalid integer argument \"%s\"", offset_start);
     command->last_argument= p;
   }
-  do_sync_with_master2(offset);
+  do_sync_with_master2(command, offset);
   return;
 }
 
@@ -4021,7 +4140,7 @@ void do_shutdown_server(struct st_comman
       break;
     }
     DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout));
-    my_sleep(1);
+    my_sleep(1000000L);
   }
 
   /* Kill the server */
@@ -5192,55 +5311,6 @@ 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 or when
   switching between different delimiters
@@ -5297,6 +5367,19 @@ void check_eol_junk(const char *eol)
 }
 
 
+bool is_delimiter(const char* p)
+{
+  uint match= 0;
+  char* delim= delimiter;
+  while (*p && *p == *delim++)
+  {
+    match++;
+    p++;
+  }
+
+  return (match == delimiter_length);
+}
+
 
 /*
   Create a command from a set of lines
@@ -5363,9 +5446,11 @@ int read_command(struct st_command** com
   if (!(command->query_buf= command->query= my_strdup(p, MYF(MY_WME))))
     die("Out of memory");
 
-  /* Calculate first word length(the command), terminated by space or ( */
+  /*
+    Calculate first word length(the command), terminated
+    by 'space' , '(' or 'delimiter' */
   p= command->query;
-  while (*p && !my_isspace(charset_info, *p) && *p != '(')
+  while (*p && !my_isspace(charset_info, *p) && *p != '(' && !is_delimiter(p))
     p++;
   command->first_word_len= (uint) (p - command->query);
   DBUG_PRINT("info", ("first_word: %.*s",
@@ -5584,7 +5669,7 @@ get_one_option(int optid, const struct m
     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' for reading: errno = %d", buff, errno);
+      die("Could not open '%s' for reading, errno: %d", buff, errno);
     cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
     cur_file->lineno= 1;
     break;
@@ -5630,6 +5715,11 @@ get_one_option(int optid, const struct m
       die("Can't use server argument");
     }
     break;
+  case OPT_LOG_DIR:
+    /* Check that the file exists */
+    if (access(opt_logdir, F_OK) != 0)
+      die("The specified log directory does not exist: '%s'", opt_logdir);
+    break;
   case 'F':
     read_embedded_server_arguments(argument);
     break;
@@ -5671,6 +5761,14 @@ int parse_args(int argc, char **argv)
   if (debug_check_flag)
     my_end_arg= MY_CHECK_ERROR;
 
+
+  if (!record)
+  {
+    /* Check that the result file exists */
+    if (result_file_name && access(result_file_name, F_OK) != 0)
+      die("The specified result file '%s' does not exist", result_file_name);
+  }
+
   return 0;
 }
 
@@ -5701,11 +5799,11 @@ void str_to_file2(const char *fname, cha
     flags|= O_TRUNC;
   if ((fd= my_open(buff, flags,
                    MYF(MY_WME | MY_FFNF))) < 0)
-    die("Could not open '%s' for writing: errno = %d", buff, errno);
+    die("Could not open '%s' for writing, errno: %d", buff, errno);
   if (append && my_seek(fd, 0, SEEK_END, MYF(0)) == MY_FILEPOS_ERROR)
-    die("Could not find end of file '%s': errno = %d", buff, errno);
+    die("Could not find end of file '%s', errno: %d", buff, errno);
   if (my_write(fd, (uchar*)str, size, MYF(MY_WME|MY_FNABP)))
-    die("write failed");
+    die("write failed, errno: %d", errno);
   my_close(fd, MYF(0));
 }
 
@@ -5725,37 +5823,6 @@ void str_to_file(const char *fname, char
 }
 
 
-void dump_result_to_log_file(char *buf, int size)
-{
-  char log_file[FN_REFLEN];
-  str_to_file(fn_format(log_file, result_file_name, opt_logdir, ".log",
-                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
-                        MY_REPLACE_EXT),
-              buf, size);
-  fprintf(stderr, "\nMore results from queries before failure can be found in %s\n",
-          log_file);
-}
-
-void dump_progress(void)
-{
-  char progress_file[FN_REFLEN];
-  str_to_file(fn_format(progress_file, result_file_name,
-                        opt_logdir, ".progress",
-                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
-                        MY_REPLACE_EXT),
-              ds_progress.str, ds_progress.length);
-}
-
-void dump_warning_messages(void)
-{
-  char warn_file[FN_REFLEN];
-
-  str_to_file(fn_format(warn_file, result_file_name, opt_logdir, ".warnings",
-                        *opt_logdir ? MY_REPLACE_DIR | MY_REPLACE_EXT :
-                        MY_REPLACE_EXT),
-              ds_warning_messages.str, ds_warning_messages.length);
-}
-
 void check_regerr(my_regex_t* r, int err)
 {
   char err_buf[1024];
@@ -6000,7 +6067,7 @@ void append_stmt_result(DYNAMIC_STRING *
   {
     uint max_length= fields[i].max_length + 1;
     my_bind[i].buffer_type= MYSQL_TYPE_STRING;
-    my_bind[i].buffer= (char *)my_malloc(max_length, MYF(MY_WME | MY_FAE));
+    my_bind[i].buffer= my_malloc(max_length, MYF(MY_WME | MY_FAE));
     my_bind[i].buffer_length= max_length;
     my_bind[i].is_null= &is_null[i];
     my_bind[i].length= &length[i];
@@ -6016,7 +6083,7 @@ void append_stmt_result(DYNAMIC_STRING *
   while (mysql_stmt_fetch(stmt) == 0)
   {
     for (i= 0; i < num_fields; i++)
-      append_field(ds, i, &fields[i], my_bind[i].buffer,
+      append_field(ds, i, &fields[i], (char*)my_bind[i].buffer,
                    *my_bind[i].length, *my_bind[i].is_null);
     if (!display_result_vertically)
       dynstr_append_mem(ds, "\n", 1);
@@ -6770,9 +6837,6 @@ void run_query(struct st_connection *cn,
 
   init_dynamic_string(&ds_warnings, NULL, 0, 256);
 
-  /* Scan for warning before sending to server */
-  scan_command_for_warnings(command);
-
   /*
     Evaluate query if this is an eval command
   */
@@ -7102,28 +7166,10 @@ void get_command_type(struct st_command*
     }
     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;
-
-      }
+      /* -- "comment" that didn't contain a mysqltest command */
+      die("Found line beginning with --  that didn't contain "\
+          "a valid mysqltest command, check your syntax or "\
+          "use # if you intended to write a comment");
     }
   }
 
@@ -7142,22 +7188,25 @@ void get_command_type(struct st_command*
 
 /*
   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 <test_name>.progress when
-  test run completes
+  up until the current line and write it to .progress file
 
 */
 
 void mark_progress(struct st_command* command __attribute__((unused)),
                    int line)
 {
+  static ulonglong progress_start= 0; // < Beware
+  DYNAMIC_STRING ds_progress;
+
   char buf[32], *end;
   ulonglong timer= timer_now();
   if (!progress_start)
     progress_start= timer;
   timer-= progress_start;
 
+  if (init_dynamic_string(&ds_progress, "", 256, 256))
+    die("Out of memory");
+
   /* Milliseconds since start */
   end= longlong2str(timer, buf, 10);
   dynstr_append_mem(&ds_progress, buf, (int)(end-buf));
@@ -7179,6 +7228,10 @@ void mark_progress(struct st_command* co
 
   dynstr_append_mem(&ds_progress, "\n", 1);
 
+  progress_file.write(&ds_progress);
+
+  dynstr_free(&ds_progress);
+
 }
 
 #ifdef HAVE_STACKTRACE
@@ -7287,7 +7340,6 @@ int main(int argc, char **argv)
   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;
   MY_INIT(argv[0]);
 
   save_file[0]= 0;
@@ -7346,11 +7398,14 @@ int main(int argc, char **argv)
   init_win_path_patterns();
 #endif
 
-  init_dynamic_string(&ds_res, "", 65536, 65536);
-  init_dynamic_string(&ds_progress, "", 0, 2048);
-  init_dynamic_string(&ds_warning_messages, "", 0, 2048);
+  init_dynamic_string(&ds_res, "", 2048, 2048);
+
   parse_args(argc, argv);
 
+  log_file.open(opt_logdir, result_file_name, ".log");
+  if (opt_mark_progress)
+    progress_file.open(opt_logdir, result_file_name, ".progress");
+
   var_set_int("$PS_PROTOCOL", ps_protocol);
   var_set_int("$SP_PROTOCOL", sp_protocol);
   var_set_int("$VIEW_PROTOCOL", view_protocol);
@@ -7439,8 +7494,8 @@ int main(int argc, char **argv)
         command->type != Q_ENABLE_PARSING &&
         command->type != Q_DISABLE_PARSING)
     {
+      /* Parsing is disabled, silently convert this line to a comment */
       command->type= Q_COMMENT;
-      scan_command_for_warnings(command);
     }
 
     if (cur_block->ok)
@@ -7608,7 +7663,7 @@ int main(int argc, char **argv)
 	  select_connection(command);
 	else
 	  select_connection_name("slave");
-	do_sync_with_master2(0);
+	do_sync_with_master2(command, 0);
 	break;
       }
       case Q_COMMENT:				/* Ignore row */
@@ -7733,8 +7788,14 @@ int main(int argc, char **argv)
     parser.current_line += current_line_inc;
     if ( opt_mark_progress )
       mark_progress(command, parser.current_line);
+
+    /* Write result from command to log file */
+    log_file.write(&ds_res);
+    dynstr_set(&ds_res, 0);
   }
 
+  log_file.close();
+
   start_lineno= 0;
 
   if (parsing_disabled)
@@ -7743,9 +7804,9 @@ int main(int argc, char **argv)
   /*
     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.
+    The entire output from test is in the log file
   */
-  if (ds_res.length)
+  if (log_file.bytes_written())
   {
     if (result_file_name)
     {
@@ -7753,22 +7814,29 @@ int main(int argc, char **argv)
 
       if (record)
       {
-	/* Recording - dump the output from test to result file */
-	str_to_file(result_file_name, ds_res.str, ds_res.length);
+	/* Recording */
+
+        /* save a copy of the log to result file */
+        if (my_copy(log_file.file_name(), result_file_name, MYF(0)) != 0)
+          die("Failed to copy '%s' to '%s', errno: %d",
+              log_file.file_name(), result_file_name, errno);
+
       }
       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);
+	/* Check that the output from test is equal to result file */
+	check_result();
       }
     }
     else
     {
-      /* No result_file_name specified to compare with, print to stdout */
-      printf("%s", ds_res.str);
+      /*
+        No result_file_name specified, the result
+        has been printed to stdout, exit with error
+        unless script has called "exit" to indicate success
+      */
+      if (abort_flag == 0)
+        die("Exit with failure! Call 'exit' in script to return with sucess");
     }
   }
   else
@@ -7776,25 +7844,8 @@ int main(int argc, char **argv)
     die("The test didn't produce any output");
   }
 
-  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
-      single query, but we do have a result file that contains data.
-      Note that we don't care, if my_stat() fails. For example, for a
-      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 (!command_executed && result_file_name)
     die("No queries executed but result file found!");
-  }
-
-  if ( opt_mark_progress && result_file_name )
-    dump_progress();
-
-  /* Dump warning messages */
-  if (result_file_name && ds_warning_messages.length)
-    dump_warning_messages();
 
   timer_output();
   /* Yes, if we got this far the test has suceeded! Sakila smiles */
@@ -7863,12 +7914,11 @@ void do_get_replace_column(struct st_com
     die("Missing argument in %s", command->query);
 
   /* Allocate a buffer for results */
-  start= buff= my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
+  start= buff= (char*)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);
@@ -7946,7 +7996,7 @@ void do_get_replace(struct st_command *c
   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));
+  start= buff= (char*)my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE));
   while (*from)
   {
     char *to= buff;

=== modified file 'libmysqld/examples/CMakeLists.txt'
--- a/libmysqld/examples/CMakeLists.txt	2008-04-02 17:52:11 +0000
+++ b/libmysqld/examples/CMakeLists.txt	2008-08-08 17:55:07 +0000
@@ -32,7 +32,6 @@ ADD_EXECUTABLE(mysql_embedded ../../clie
 TARGET_LINK_LIBRARIES(mysql_embedded mysys yassl taocrypt zlib debug dbug regex strings ws2_32)
 ADD_DEPENDENCIES(mysql_embedded libmysqld)
 
-ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.c)
 TARGET_LINK_LIBRARIES(mysqltest_embedded mysys yassl taocrypt zlib debug dbug regex strings ws2_32)
 ADD_DEPENDENCIES(mysqltest_embedded libmysqld)
 

=== modified file 'libmysqld/examples/Makefile.am'
--- a/libmysqld/examples/Makefile.am	2007-12-07 14:35:28 +0000
+++ b/libmysqld/examples/Makefile.am	2008-08-08 17:55:07 +0000
@@ -41,7 +41,7 @@ LDADD =		@CLIENT_EXTRA_LDFLAGS@ ../libmy
                 @NDB_SCI_LIBS@
 
 mysqltest_embedded_LINK = $(CXXLINK)
-nodist_mysqltest_embedded_SOURCES =	mysqltest.c
+nodist_mysqltest_embedded_SOURCES =	mysqltest.cc
 mysqltest_embedded_LDADD =	$(LDADD) $(top_builddir)/regex/libregex.a
 
 nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \

=== modified file 'mysql-test/extra/rpl_tests/rpl_row_sp002.test'
--- a/mysql-test/extra/rpl_tests/rpl_row_sp002.test	2008-04-23 09:50:50 +0000
+++ b/mysql-test/extra/rpl_tests/rpl_row_sp002.test	2008-08-08 17:55:07 +0000
@@ -214,7 +214,7 @@ START TRANSACTION;
 -- disable_query_log
 -- disable_result_log
 let $n=50;
-while ($n>3)
+while ($n)
 {
   eval call test.p3($n);
   dec $n;

=== renamed file 'mysql-test/include/analyze_failure_sync_with_master.test' => 'mysql-test/include/analyze-sync_with_master.test'
--- a/mysql-test/include/analyze_failure_sync_with_master.test	2006-10-24 15:36:46 +0000
+++ b/mysql-test/include/analyze-sync_with_master.test	2008-08-04 19:54:44 +0000
@@ -1,15 +1,6 @@
-# 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,);
+SHOW PROCESSLIST;
 
-vertical_results;
+let $binlog_name= query_get_value("SHOW MASTER STATUS", File, 1);
+eval SHOW BINLOG EVENTS IN '$binlog_name';
 
-echo == MASTER ===========================================================;
-connection master;
-show master status;
-show slave status;
-
-echo == SLAVE ===========================================================;
-connection slave;
-show master status;
-show slave status;
+exit;
\ No newline at end of file

=== modified file 'mysql-test/include/mysqltest-x.inc'
--- a/mysql-test/include/mysqltest-x.inc	2005-09-05 14:50:32 +0000
+++ b/mysql-test/include/mysqltest-x.inc	2008-08-04 19:54:44 +0000
@@ -1,2 +1,3 @@
 echo Output from mysqltest-x.inc;
+exit;
 

=== modified file 'mysql-test/include/not_as_root.inc'
--- a/mysql-test/include/not_as_root.inc	2006-04-24 10:01:16 +0000
+++ b/mysql-test/include/not_as_root.inc	2008-08-04 10:38:50 +0000
@@ -1,4 +1,3 @@
--- require r/not_as_root.require
-disable_query_log;
-eval select "$MYSQL_TEST_ROOT" as running_as_root;
-enable_query_log;
+if ($MYSQL_TEST_ROOT){
+  skip Not as root;
+}

=== modified file 'mysql-test/lib/mtr_cases.pm'
--- a/mysql-test/lib/mtr_cases.pm	2008-08-04 14:30:50 +0000
+++ b/mysql-test/lib/mtr_cases.pm	2008-08-08 17:55:07 +0000
@@ -120,7 +120,7 @@ sub collect_test_cases ($$) {
       }
       if ( not $found )
       {
-	mtr_error("Could not find $tname in any suite");
+	mtr_error("Could not find '$tname' in '$suites' suite(s)");
       }
     }
   }
@@ -537,23 +537,36 @@ sub optimize_cases {
       }
     }
 
-
     # =======================================================
     # Check that engine selected by
     # --default-storage-engine=<engine> is supported
     # =======================================================
+    my %builtin_engines = ('myisam' => 1, 'memory' => 1);
+
     foreach my $opt ( @{$tinfo->{master_opt}} ) {
       my $default_engine=
 	mtr_match_prefix($opt, "--default-storage-engine=");
 
       if (defined $default_engine){
-	if ( ! exists $::mysqld_variables{$default_engine} )
-	{
-	 $tinfo->{'skip'}= 1;
-	 $tinfo->{'comment'}=
-	 "'$default_engine' not supported";
 
+	#print " $tinfo->{name}\n";
+	#print " - The test asked to use '$default_engine'\n";
+
+	#my $engine_value= $::mysqld_variables{$default_engine};
+	#print " - The mysqld_variables says '$engine_value'\n";
+
+	if ( ! exists $::mysqld_variables{$default_engine} and
+	     ! exists $builtin_engines{$default_engine} )
+	{
+	  $tinfo->{'skip'}= 1;
+	  $tinfo->{'comment'}=
+	    "'$default_engine' not supported";
 	}
+
+	$tinfo->{'ndb_test'}= 1
+	  if ( $default_engine =~ /^ndb/i );
+	$tinfo->{'innodb_test'}= 1
+	  if ( $default_engine =~ /^innodb/i );
       }
     }
   }
@@ -677,12 +690,16 @@ sub collect_one_test_case {
      name          => "$suitename.$tname",
      path          => "$testdir/$filename",
 
-     # TODO allow nonexistsing result file
-     # in that case .test must issue "exit" otherwise test
-     # should fail by default
-     result_file   => "$resdir/$tname.result",
     );
 
+  my $result_file= "$resdir/$tname.result";
+  if (-f $result_file) {
+    # Allow nonexistsing result file
+    # in that case .test must issue "exit" otherwise test
+    # should fail by default
+    $tinfo->{result_file}= $result_file;
+  }
+
   # ----------------------------------------------------------------------
   # Skip some tests but include in list, just mark them as skipped
   # ----------------------------------------------------------------------

=== modified file 'mysql-test/lib/mtr_report.pm'
--- a/mysql-test/lib/mtr_report.pm	2008-08-04 14:30:50 +0000
+++ b/mysql-test/lib/mtr_report.pm	2008-08-08 17:55:07 +0000
@@ -103,17 +103,24 @@ sub mtr_report_test ($) {
   my ($tinfo)= @_;
   _mtr_report_test_name($tinfo);
 
-  if ($tinfo->{'result'} eq 'MTR_RES_FAILED'){
+  my $comment=  $tinfo->{'comment'};
+  my $logfile=  $tinfo->{'logfile'};
+  my $warnings= $tinfo->{'warnings'};
+  my $result=   $tinfo->{'result'};
 
-    if ( defined $tinfo->{'warnings'} )
+  if ($result eq 'MTR_RES_FAILED'){
+
+    if ( $warnings )
     {
       mtr_report("[ fail ]  Found warnings in server log file!");
-      mtr_report($tinfo->{'warnings'});
+      mtr_report($warnings);
       return;
     }
-    if ( defined $tinfo->{'timeout'} )
+    my $timeout= $tinfo->{'timeout'};
+    if ( $timeout )
     {
-      mtr_report("[ fail ]  timeout");
+      mtr_report("[ fail ]  timeout after $timeout minutes");
+      mtr_report("\n$tinfo->{'comment'}");
       return;
     }
     else
@@ -121,43 +128,42 @@ sub mtr_report_test ($) {
       mtr_report("[ fail ]");
     }
 
-    if ( $tinfo->{'comment'} )
+    if ( $logfile )
+    {
+      # Test failure was detected by test tool and its report
+      # about what failed has been saved to file. Display the report.
+      mtr_report("\n$logfile\n");
+    }
+    if ( $comment )
     {
       # The test failure has been detected by mysql-test-run.pl
       # when starting the servers or due to other error, the reason for
       # failing the test is saved in "comment"
-      mtr_report("\nERROR: $tinfo->{'comment'}");
+      mtr_report("\n$comment\n");
     }
-    elsif ( $tinfo->{logfile} )
-    {
-      # Test failure was detected by test tool and its report
-      # about what failed has been saved to file. Display the report.
-      mtr_report("\n");
-      mtr_report($tinfo->{logfile}, "\n");
 
-    }
-    else
+    if ( !$logfile and !$comment )
     {
       # Neither this script or the test tool has recorded info
       # about why the test has failed. Should be debugged.
-      mtr_report("\nUnexpected termination, probably when starting mysqld");;
+      mtr_report("\nUnknown result, neither 'comment' or 'logfile' set");
     }
   }
-  elsif ($tinfo->{'result'} eq 'MTR_RES_SKIPPED')
+  elsif ($result eq 'MTR_RES_SKIPPED')
   {
     if ( $tinfo->{'disable'} )
     {
-      mtr_report("[ disabled ]  $tinfo->{'comment'}");
+      mtr_report("[ disabled ]  $comment");
     }
-    elsif ( $tinfo->{'comment'} )
+    elsif ( $comment )
     {
       if ( $tinfo->{skip_detected_by_test} )
       {
-	mtr_report("[ skip ]. $tinfo->{'comment'}");
+	mtr_report("[ skip ]. $comment");
       }
       else
       {
-	mtr_report("[ skip ]  $tinfo->{'comment'}");
+	mtr_report("[ skip ]  $comment");
       }
     }
     else
@@ -165,7 +171,7 @@ sub mtr_report_test ($) {
       mtr_report("[ skip ]");
     }
   }
-  elsif ($tinfo->{'result'} eq 'MTR_RES_PASSED')
+  elsif ($result eq 'MTR_RES_PASSED')
   {
     my $timer_str= $tinfo->{timer} || "";
     $tot_real_time += ($timer_str/1000);

=== modified file 'mysql-test/mysql-test-run.pl'
--- a/mysql-test/mysql-test-run.pl	2008-08-07 20:51:09 +0000
+++ b/mysql-test/mysql-test-run.pl	2008-08-08 17:55:07 +0000
@@ -98,7 +98,7 @@ our $exe_mysqladmin;
 our $exe_mysqltest;
 our $exe_libtool;
 
-my $opt_big_test= 0;
+our $opt_big_test= 0;
 
 our @opt_combinations;
 
@@ -166,7 +166,7 @@ my $opt_repeat= 1;
 my $opt_retry= 3;
 my $opt_retry_failure= 2;
 
-my $opt_parallel;
+my $opt_parallel= $ENV{MTR_PARALLEL};
 
 my $opt_strace_client;
 
@@ -299,8 +299,9 @@ sub main {
     my $tinfo = My::Test->new
       (
        name           => 'report_features',
-       result_file    => undef, # Prints result
+       # No result_file => Prints result
        path           => 'include/report-features.test'.
+       template_path  => "include/default_my.cnf",
        master_opt     => [],
        slave_opt      => [],
       );
@@ -623,6 +624,7 @@ sub run_worker ($) {
   }
 
   setup_vardir();
+  check_running_as_root();
   mysql_install_db($thread_num);
 
   if ( using_extern() ) {
@@ -1056,6 +1058,13 @@ sub command_line_setup {
     {
       mtr_error("Can't use --extern with --embedded-server");
     }
+
+    if ( $opt_gdb || $opt_ddd || $opt_manual_gdb || $opt_manual_ddd ||
+	 $opt_manual_debug || $opt_debugger )
+    {
+      mtr_error("You need to use the client debug options for the",
+		"embedded server. Ex: --client-gdb");
+    }
   }
 
   # --------------------------------------------------------------------------
@@ -1920,7 +1929,6 @@ sub  check_running_as_root () {
   # the file will not return 0000
   my $file_mode= (stat($test_file))[2] & 07777;
 
-  $ENV{'MYSQL_TEST_ROOT'}= "NO";
   mtr_verbose("result: $result, file_mode: $file_mode");
   if ($result eq "MySQL" && $file_mode == 0)
   {
@@ -2370,7 +2378,6 @@ sub initialize_servers {
       mysql_install_db(0);
     }
   }
-  check_running_as_root();
 }
 
 
@@ -2735,6 +2742,120 @@ sub check_testcase($$)
 }
 
 
+# Start run mysqltest on one server
+#
+# RETURN VALUE
+#  0 OK
+#  1 Check failed
+#
+sub start_run_one ($$) {
+  my ($mysqld, $run)= @_;
+
+  my $name= "$run-".$mysqld->name();
+
+  my $args;
+  mtr_init_args(\$args);
+
+  mtr_add_arg($args, "--defaults-file=%s", $path_config_file);
+  mtr_add_arg($args, "--defaults-group-suffix=%s", $mysqld->after('mysqld'));
+
+  mtr_add_arg($args, "--silent");
+  mtr_add_arg($args, "--skip-safemalloc");
+  mtr_add_arg($args, "--test-file=%s", "include/$run.test");
+
+  my $errfile= "$opt_vardir/tmp/$name.err";
+  my $proc= My::SafeProcess->new
+    (
+     name          => $name,
+     path          => $exe_mysqltest,
+     error         => $errfile,
+     output        => $errfile,
+     args          => \$args,
+     user_data     => $errfile,
+    );
+  mtr_verbose("Started $proc");
+  return $proc;
+}
+
+
+#
+# Run script on all servers, collect results
+#
+# RETURN VALUE
+#  0 ok
+#  1 Failure
+
+sub run_on_all($$)
+{
+  my ($tinfo, $run)= @_;
+  my $tname= $tinfo->{name};
+
+  # Start the mysqltest processes in parallel to save time
+  # also makes it possible to wait for any process to exit during the check
+  # and to have a timeout process
+  my %started;
+  foreach my $mysqld ( mysqlds() )
+  {
+    if ( defined $mysqld->{'proc'} )
+    {
+      my $proc= start_run_one($mysqld, $run);
+      $started{$proc->pid()}= $proc;
+    }
+  }
+
+  # Return immediately if no check proceess was started
+  return 0 unless ( keys %started );
+
+  my $timeout_proc= My::SafeProcess->timer(60); # Seconds
+
+  while (1){
+    my $result;
+    my $proc= My::SafeProcess->wait_any();
+    mtr_report("Got $proc");
+
+    if ( delete $started{$proc->pid()} ) {
+
+      # One mysqltest process returned
+      my $err_file= $proc->user_data();
+      my $res= $proc->exit_status();
+
+      # Append the report from .err file
+      $tinfo->{comment}.= " == $err_file ==\n";
+      $tinfo->{comment}.= mtr_grab_file($err_file);
+      $tinfo->{comment}.= "\n";
+
+      # Remove the .err file
+      unlink($err_file);
+
+      if ( keys(%started) == 0){
+	# All completed
+	$timeout_proc->kill();
+	return 0;
+      }
+
+      # Wait for next process to exit
+      next;
+    }
+    elsif ( $proc eq $timeout_proc ) {
+      $tinfo->{comment}.= "Timeout $timeout_proc expired for running '$run'";
+    }
+    else {
+      # Unknown process returned, most likley a crash, abort everything
+      $tinfo->{comment}.=
+	"Unexpected process $proc returned during ".
+	"execution of '$run'";
+    }
+
+    # Kill any check processes still running
+    map($_->kill(), values(%started));
+
+    $timeout_proc->kill();
+
+    return 1;
+  }
+}
+
+
 sub mark_log {
   my ($log, $tinfo)= @_;
   my $log_msg= "CURRENT_TEST: $tinfo->{name}\n";
@@ -2772,6 +2893,26 @@ sub find_testcase_skipped_reason($)
 }
 
 
+sub find_analyze_request
+{
+  # Open the test log file
+  my $F= IO::File->new($path_current_testlog)
+    or return;
+  my $analyze;
+
+  while ( my $line= <$F> )
+  {
+    # Look for "reason: <reason for skipping test>"
+    if ( $line =~ /analyze: (.*)/ )
+    {
+      $analyze= $1;
+    }
+  }
+
+  return $analyze;
+}
+
+
 # Return timezone value of tinfo or default value
 sub timezone {
   my ($tinfo)= @_;
@@ -2976,6 +3117,13 @@ sub run_testcase ($) {
       }
       elsif ( $res == 1 )
       {
+	# Check if the test tool requests that
+	# an analyze script should be run
+	my $analyze= find_analyze_request();
+	if ($analyze){
+	  run_on_all($tinfo, "analyze-$analyze");
+	}
+
 	# Test case failure reported by mysqltest
 	report_failure_and_restart($tinfo);
       }
@@ -3034,8 +3182,10 @@ sub run_testcase ($) {
     # ----------------------------------------------------
     if ( $proc eq $test_timeout_proc )
     {
-      mtr_report("Test case timeout!");
-      $tinfo->{'timeout'}= 1;           # Mark as timeout
+      $tinfo->{comment}=
+	"Test case timeout after $opt_testcase_timeout minute(s)\n\n";
+      $tinfo->{'timeout'}= $opt_testcase_timeout; # Mark as timeout
+      run_on_all($tinfo, 'analyze-timeout');
       report_failure_and_restart($tinfo);
       return 1;
     }
@@ -3371,7 +3521,6 @@ sub report_failure_and_restart ($) {
   $tinfo->{'failures'}=  $test_failures + 1;
 
 
-  my $logfile= $path_current_testlog;
   if ( $tinfo->{comment} )
   {
     # The test failure has been detected by mysql-test-run.pl
@@ -3379,12 +3528,17 @@ sub report_failure_and_restart ($) {
     # failing the test is saved in "comment"
     ;
   }
-  elsif ( defined $logfile and -f $logfile )
+
+  if ( !defined $tinfo->{logfile} )
   {
-    # Test failure was detected by test tool and its report
-    # about what failed has been saved to file. Save the report
-    # in tinfo
-    $tinfo->{logfile}= mtr_fromfile($logfile);
+    my $logfile= $path_current_testlog;
+    if ( defined $logfile and -f $logfile )
+    {
+      # Test failure was detected by test tool and its report
+      # about what failed has been saved to file. Save the report
+      # in tinfo
+      $tinfo->{logfile}= mtr_fromfile($logfile);
+    }
   }
 
   after_failure($tinfo);
@@ -3977,6 +4131,16 @@ sub start_servers($) {
 				 $mysqld->{'proc'}) == 0) {
       $tinfo->{comment}=
 	"Failed to start ".$mysqld->name();
+
+      my $logfile= $mysqld->value('log-error');
+      if ( defined $logfile and -f $logfile )
+      {
+	$tinfo->{logfile}= mtr_fromfile($logfile);
+      }
+      else
+      {
+	$tinfo->{logfile}= "Could not open server logfile: '$logfile'";
+      }
       return 1;
     }
   }
@@ -4097,8 +4261,6 @@ sub start_mysqltest ($) {
     mtr_add_arg($args, "--sleep=%d", $opt_sleep);
   }
 
-  client_debug_arg($args, "mysqltest");
-
   if ( $opt_ssl )
   {
     # Turn on SSL for _all_ test cases if option --ssl was used
@@ -4159,6 +4321,8 @@ sub start_mysqltest ($) {
     mtr_add_arg($args, "--result-file=%s", $tinfo->{'result_file'});
   }
 
+  client_debug_arg($args, "mysqltest");
+
   if ( $opt_record )
   {
     mtr_add_arg($args, "--record");

=== modified file 'mysql-test/r/mysqltest.result'
--- a/mysql-test/r/mysqltest.result	2008-07-22 10:51:13 +0000
+++ b/mysql-test/r/mysqltest.result	2008-08-08 17:55:07 +0000
@@ -294,7 +294,7 @@ var5 from query that returns no row
 failing query in let
 mysqltest: At line 1: Error running query 'failing query': 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 'failing query' at line 1
 mysqltest: At line 1: Missing required argument 'filename' to command 'source'
-mysqltest: At line 1: Could not open './non_existingFile' for reading
+mysqltest: At line 1: Could not open './non_existingFile' for reading, errno: 2
 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
 
@@ -444,7 +444,7 @@ ERROR 3D000: No database selected
 Output from mysqltest-x.inc
 Output from mysqltest-x.inc
 Output from mysqltest-x.inc
-mysqltest: Could not open './non_existing_file.inc' for reading: errno = 2
+mysqltest: Could not open './non_existing_file.inc' for reading, errno: 2
 failing_statement;
 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 'failing_statement' at line 1
 failing_statement;
@@ -487,8 +487,6 @@ mysqltest: At line 3: query 'create tabl
 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
-
-More results from queries before failure can be found in MYSQLTEST_VARDIR/log/bug11731.log
 drop table t1;
 Multi statement using expected error
 create table t1 (a int primary key);
@@ -732,4 +730,14 @@ file2.txt
 SELECT 'c:\\a.txt' AS col;
 col
 z
+hej
+mysqltest: At line 1: Found junk ' != 143' after $variable in expression
+select 1;
+1
+1
+select 1;
+1
+1
+-- a comment for the server;
+mysqltest: At line 1: Found line beginning with --  that didn't contain a valid mysqltest command, check your syntax or use # if you intended to write a comment
 End of tests

=== removed file 'mysql-test/r/not_as_root.require'
--- a/mysql-test/r/not_as_root.require	2006-04-24 08:21:09 +0000
+++ b/mysql-test/r/not_as_root.require	1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
-running_as_root
-NO

=== modified file 'mysql-test/t/execution_constants.test'
--- a/mysql-test/t/execution_constants.test	2006-11-13 16:06:45 +0000
+++ b/mysql-test/t/execution_constants.test	2008-08-04 10:38:50 +0000
@@ -41,12 +41,19 @@ while ($i)
   error 0,1436 //
   eval $query_head 0 $query_tail//
 
-  if ($mysql_errno != 1436)
+  if ($mysql_errno)
   {
     # We reached the place where we reported an error about the stack limit,
     # and we successfully returned the error.  That means that at the stack
     # limit, we still have enough space reserved to report an error.
     let $i = 1//
+
+    # Check that mysql_errno is 1436
+    if (`select $mysql_errno != 1436`)
+    {
+      die Wrong error triggered, expected 1436 but got $mysql_errno//
+    }
+
   }
 
   # Multiplying by three stack frames should be fine enough resolution.

=== modified file 'mysql-test/t/fix_priv_tables.test'
--- a/mysql-test/t/fix_priv_tables.test	2007-04-04 13:40:40 +0000
+++ b/mysql-test/t/fix_priv_tables.test	2008-08-04 19:54:44 +0000
@@ -51,7 +51,8 @@ echo;
 -- disable_query_log
 
 # Run the mysql_fix_privilege_tables.sql using "mysql --force"
---exec $MYSQL --force mysql < $MYSQL_FIX_PRIVILEGE_TABLES > $MYSQLTEST_VARDIR/log/fix_priv_tables.log 2>&1
+--exec $MYSQL --force mysql < $MYSQL_FIX_PRIVILEGE_TABLES > $MYSQLTEST_VARDIR/tmp/fix_priv_tables.log 2>&1
+--remove_file $MYSQLTEST_VARDIR/tmp/fix_priv_tables.log
 
 -- enable_query_log
 -- enable_result_log

=== modified file 'mysql-test/t/mysqltest.test'
--- a/mysql-test/t/mysqltest.test	2008-07-22 10:51:13 +0000
+++ b/mysql-test/t/mysqltest.test	2008-08-08 17:55:07 +0000
@@ -1229,7 +1229,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; echo OK;" | $MYSQL_TEST 2>&1
+--exec echo "replace_result a b; echo OK; exit;" | $MYSQL_TEST 2>&1
 --error 1
 --exec echo "--replace_result a b c" | $MYSQL_TEST 2>&1
 --error 1
@@ -1293,7 +1293,7 @@ while ($i)
   dec $i;
 }
 EOF
---exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK;" | $MYSQL_TEST 2>&1
+--exec echo "source $MYSQLTEST_VARDIR/tmp/mysqltest.sql; echo OK; exit;" | $MYSQL_TEST 2>&1
 remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
 
 # Repeat connect/disconnect
@@ -1500,6 +1500,7 @@ echo Multi statement using expected erro
 --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
+--exec echo "exit;"                                   >> $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
@@ -1692,6 +1693,7 @@ EOF
 --diff_files $MYSQLTEST_VARDIR/tmp/diff1.tmp $MYSQLTEST_VARDIR/tmp/diff4.tmp
 --error 1
 --diff_files $MYSQLTEST_VARDIR/tmp/diff4.tmp $MYSQLTEST_VARDIR/tmp/diff1.tmp
+exit;
 EOF
 
 # Execute the above diffs, and send their output to /dev/null - only
@@ -2147,5 +2149,39 @@ rmdir $MYSQLTEST_VARDIR/tmp/testdir;
 --replace_result c:\\a.txt z
 SELECT 'c:\\a.txt' AS col;
 
+#
+# Bug #32307  	mysqltest - does not detect illegal if syntax
+#
+
+let $test= 1;
+if ($test){
+  echo hej;
+}
+
+--write_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql
+if ($mysql_errno != 1436)
+{
+ echo ^ Should not be allowed!
+}
+EOF
+--error 1
+--exec $MYSQL_TEST < $MYSQLTEST_VARDIR/tmp/mysqltest.sql 2>&1
+remove_file $MYSQLTEST_VARDIR/tmp/mysqltest.sql;
+
+
+# ----------------------------------------------------------------------------
+# Test that -- is not allowed as comment, only as mysqltest builtin command
+# ----------------------------------------------------------------------------
+
+# valid
+select 1;
+--query select 1
+--query -- a comment for the server
+
+# Not valid, "select" is not a mysqltest command
+--error 1
+--exec echo "--select 1;" | $MYSQL_TEST 2>&1
+
+
 --echo End of tests
 

=== modified file 'mysql-test/t/openssl_1.test'
--- a/mysql-test/t/openssl_1.test	2007-12-07 14:35:28 +0000
+++ b/mysql-test/t/openssl_1.test	2008-08-08 17:55:07 +0000
@@ -101,7 +101,7 @@ drop table t1;
 # - Apparently selecting a cipher doesn't work at all
 # - Usa a cipher that both yaSSL and OpenSSL supports
 #
---exec echo "SHOW STATUS LIKE 'Ssl_cipher';" > $MYSQLTEST_VARDIR/tmp/test.sql
+--exec echo "SHOW STATUS LIKE 'Ssl_cipher'; exit;" > $MYSQLTEST_VARDIR/tmp/test.sql
 --exec $MYSQL_TEST --ssl-cipher=DHE-RSA-AES256-SHA < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
 
 #
@@ -155,18 +155,18 @@ SET GLOBAL event_scheduler=0;
 #
 # Test to connect using a list of ciphers
 #
---exec echo "SHOW STATUS LIKE 'Ssl_cipher';" > $MYSQLTEST_VARDIR/tmp/test.sql
+--exec echo "SHOW STATUS LIKE 'Ssl_cipher'; exit;" > $MYSQLTEST_VARDIR/tmp/test.sql
 --exec $MYSQL_TEST --ssl-cipher=UNKNOWN-CIPHER:AES128-SHA < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
 
 
 # Test to connect using a specifi cipher
 #
---exec echo "SHOW STATUS LIKE 'Ssl_cipher';" > $MYSQLTEST_VARDIR/tmp/test.sql
+--exec echo "SHOW STATUS LIKE 'Ssl_cipher'; exit;" > $MYSQLTEST_VARDIR/tmp/test.sql
 --exec $MYSQL_TEST --ssl-cipher=AES128-SHA < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
 
 # Test to connect using an unknown cipher
 #
---exec echo "SHOW STATUS LIKE 'Ssl_cipher';" > $MYSQLTEST_VARDIR/tmp/test.sql
+--exec echo "SHOW STATUS LIKE 'Ssl_cipher'; exit" > $MYSQLTEST_VARDIR/tmp/test.sql
 --error 1
 --exec $MYSQL_TEST --ssl-cipher=UNKNOWN-CIPHER < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1
 

=== modified file 'mysql-test/t/ps.test'
--- a/mysql-test/t/ps.test	2008-05-21 10:17:29 +0000
+++ b/mysql-test/t/ps.test	2008-08-08 17:55:07 +0000
@@ -1665,7 +1665,7 @@ DROP PROCEDURE IF EXISTS p1;
 let $iterations= 100;
 --disable_query_log
 --disable_result_log
-while ($iterations > 0)
+while ($iterations)
 {
   --error ER_PARSE_ERROR
   PREPARE stmt FROM "CREATE PROCEDURE p1()";

Thread
bzr commit into mysql-6.0 branch (msvensson:2699) Magnus Svensson8 Aug