diff options
author | unknown <msvensson@neptunus.(none)> | 2005-09-02 08:59:59 +0200 |
---|---|---|
committer | unknown <msvensson@neptunus.(none)> | 2005-09-02 08:59:59 +0200 |
commit | 7cbc039c9e7169ddb448627da6c98acd769f747f (patch) | |
tree | b72639980d52da090b2dd1dc8c17f80abd2b967e | |
parent | 22089ea6bb7e6774f2ba853e3ab756ad228ff909 (diff) | |
parent | b287e9e5202cdf8c5f7b1fe3f8fad4b3d0d3e05b (diff) | |
download | mariadb-git-7cbc039c9e7169ddb448627da6c98acd769f747f.tar.gz |
Merge neptunus.(none):/home/msvensson/mysql/mysql-5.0
into neptunus.(none):/home/msvensson/mysql/mysql-5.1
configure.in:
Auto merged
include/my_global.h:
Auto merged
mysql-test/mysql-test-run.pl:
Auto merged
mysql-test/mysql-test-run.sh:
Auto merged
scripts/Makefile.am:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/mysqld.cc:
Auto merged
sql/examples/ha_tina.cc:
Auto merged
sql/sql_acl.h:
Auto merged
sql/sql_parse.cc:
Auto merged
sql/sql_table.cc:
Auto merged
storage/myisam/mi_extra.c:
Auto merged
storage/ndb/include/kernel/signaldata/FsRef.hpp:
Auto merged
storage/ndb/src/kernel/blocks/backup/BackupInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp:
Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp:
Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp:
Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
Auto merged
storage/ndb/src/kernel/vm/SimulatedBlock.cpp:
Auto merged
storage/ndb/src/kernel/vm/SimulatedBlock.hpp:
Auto merged
storage/ndb/src/mgmclient/CommandInterpreter.cpp:
Auto merged
storage/ndb/src/mgmsrv/ConfigInfo.cpp:
Auto merged
storage/ndb/src/ndbapi/ndberror.c:
Auto merged
sql/sql_acl.cc:
Merge 5.0 -> 5.1
storage/ndb/src/kernel/blocks/dbdih/Makefile.am:
Merge 5.0 -> 5.1
101 files changed, 2417 insertions, 1124 deletions
diff --git a/BUILD/compile-pentium-icc b/BUILD/compile-pentium-icc index eee8b6c9d90..bf550a4b574 100755 --- a/BUILD/compile-pentium-icc +++ b/BUILD/compile-pentium-icc @@ -8,29 +8,16 @@ path=`dirname $0` CC=icc CXX=icpc CXXLD="$CXX -static-libcxa" -export CC CXX - - -extra_flags="$pentium_cflags $debug_cflags $max_cflags -USAFEMALLOC -UFORCE_INIT_OF_VARS -DHAVE_purify -DMYSQL_SERVER_SUFFIX=-valgrind-max" - -# Disable following warnings as these are generated by header files: -# 161 unrecognized pragma -# 444 destructor for base class xxx is not virtual -# 279 controlling expression is constant -# 810 conversion from ulonglong to ulong with cast -# 981 operands are evaluated in unspecified order -# 1292 warning for unknown 'attribute' options -# 1469 "xxx" clobber ignored -# 1572 floating-point equality and inequality comparisons are unreliable - -# In C++ -# 869 parameter "xxx" was never referenced -# (Problem with virtual functions) -# 874 support for placement delete is disabled +export CC CXX CXXLD c_warnings="" cxx_warnings="" -extra_flags="-O3 -unroll2 -ip -mp -no-gcc -restrict" +extra_flags="$fast_cflags -unroll2 -ip -mp -restrict" + +# Use -no-ipo if you get this error +# IPO link: can not find "-lstdc++_shared" +# icpc: error: problem during multi-file optimization compilation (code 1) +extra_flags="$extra_flags -no-ipo" base_cxxflags="-fno-exceptions -fno-rtti" extra_configs="$pentium_configs $static_link" diff --git a/BUILD/compile-pentium-icc-yassl b/BUILD/compile-pentium-icc-yassl new file mode 100644 index 00000000000..53b191e4db3 --- /dev/null +++ b/BUILD/compile-pentium-icc-yassl @@ -0,0 +1,24 @@ +#! /bin/sh + +path=`dirname $0` +. "$path/SETUP.sh" + +# Note that we can't use ccache with icc as the generated .deps file will +# then contain wrong information +CC=icc +CXX=icpc +CXXLD="$CXX -static-libcxa" +export CC CXX CXXLD + +c_warnings="" +cxx_warnings="" +extra_flags="$fast_cflags -unroll2 -ip -mp -restrict" + +# Use -no-ipo if you get this error +# IPO link: can not find "-lstdc++_shared" +# icpc: error: problem during multi-file optimization compilation (code 1) +extra_flags="$extra_flags -no-ipo" +base_cxxflags="-fno-exceptions -fno-rtti" +extra_configs="$pentium_configs $static_link --with-yassl" + +. "$path/FINISH.sh" diff --git a/client/mysqltest.c b/client/mysqltest.c index 57b81e46b66..c968fb2a33a 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -105,12 +105,11 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, /* ************************************************************************ */ /* - A line that starts with !$ or $S, and the list of error codes to - --error are stored in an internal array of structs. This struct can - hold numeric SQL error codes or SQLSTATE codes as strings. The - element next to the last active element in the list is set to type - ERR_EMPTY. When an SQL statement return an error we use this list to - check if this is an expected error. + The list of error codes to --error are stored in an internal array of + structs. This struct can hold numeric SQL error codes or SQLSTATE codes + as strings. The element next to the last active element in the list is + set to type ERR_EMPTY. When an SQL statement return an error we use + this list to check if this is an expected error. */ enum match_err_type @@ -148,13 +147,13 @@ static uint global_expected_errors; static int record = 0, opt_sleep=0; static char *db = 0, *pass=0; -const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./"; +const char *user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./"; static int port = 0; static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 0; static my_bool tty_password= 0, ps_protocol= 0, ps_protocol_enabled= 0; static int parsing_disabled= 0; static uint start_lineno, *lineno; -const char* manager_user="root",*manager_host=0; +const char *manager_user="root",*manager_host=0; char *manager_pass=0; int manager_port=MYSQL_MANAGER_PORT; int manager_wait_timeout=3; @@ -164,9 +163,16 @@ static char **default_argv; static const char *load_default_groups[]= { "mysqltest","client",0 }; static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer; -static FILE* file_stack[MAX_INCLUDE_DEPTH]; -static FILE** cur_file; -static FILE** file_stack_end; +typedef struct +{ + FILE* file; + const char *file_name; +} test_file; + +static test_file file_stack[MAX_INCLUDE_DEPTH]; +static test_file* cur_file; +static test_file* file_stack_end; + static uint lineno_stack[MAX_INCLUDE_DEPTH]; static char TMPDIR[FN_REFLEN]; static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER; @@ -320,7 +326,7 @@ Q_COMMENT_WITH_COMMAND /* this should really be called command */ struct st_query { - char *query, *query_buf,*first_argument,*end; + char *query, *query_buf,*first_argument,*last_argument,*end; int first_word_len; my_bool abort_on_error, require_file; match_err expected_errno[MAX_EXPECTED_ERRORS]; @@ -336,7 +342,7 @@ const char *command_names[]= "connect", /* the difference between sleep and real_sleep is that sleep will use the delay from command line (--sleep) if there is one. - real_sleep always uses delay from it's argument. + real_sleep always uses delay from mysqltest's command line argument. the logic is that sometimes delays are cpu-dependent (and --sleep can be used to set this delay. real_sleep is used for cpu-independent delays @@ -423,7 +429,7 @@ static void var_free(void* v); int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname); void reject_dump(const char *record_file, char *buf, int size); -int close_connection(struct st_query* q); +int close_connection(struct st_query*); static void set_charset(struct st_query*); VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing); @@ -449,9 +455,9 @@ static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name); void free_pointer_array(POINTER_ARRAY *pa); static int initialize_replace_buffer(void); static void free_replace_buffer(void); -static void do_eval(DYNAMIC_STRING* query_eval, const char *query); +static void do_eval(DYNAMIC_STRING *query_eval, const char *query); void str_to_file(const char *fname, char *str, int size); -int do_server_op(struct st_query* q,const char *op); +int do_server_op(struct st_query *q,const char *op); struct st_replace *glob_replace; static char *out_buff; @@ -479,9 +485,9 @@ static int normal_handle_error(const char *query, struct st_query *q, MYSQL *mysql, DYNAMIC_STRING *ds); static int normal_handle_no_error(struct st_query *q); -static void do_eval(DYNAMIC_STRING* query_eval, const char* query) +static void do_eval(DYNAMIC_STRING* query_eval, const char *query) { - const char* p; + const char *p; register char c; register int escaped = 0; VAR* v; @@ -538,10 +544,13 @@ static void close_cons() static void close_files() { DBUG_ENTER("close_files"); - for (; cur_file != file_stack ; cur_file--) + for (; cur_file != (file_stack-1) ; cur_file--) { - if (*cur_file != stdin && *cur_file) - my_fclose(*cur_file,MYF(0)); + DBUG_PRINT("info", ("file_name: %s", cur_file->file_name)); + if (cur_file->file && cur_file->file != stdin) + my_fclose(cur_file->file, MYF(0)); + my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); + cur_file->file_name= 0; } DBUG_VOID_RETURN; } @@ -584,14 +593,18 @@ static void free_used_memory() DBUG_VOID_RETURN; } -static void die(const char* fmt, ...) +static void die(const char *fmt, ...) { va_list args; DBUG_ENTER("die"); va_start(args, fmt); if (fmt) { - fprintf(stderr, "%s: ", my_progname); + fprintf(stderr, "mysqltest: "); + if (cur_file && cur_file != file_stack) + fprintf(stderr, "In included file \"%s\": ", + cur_file->file_name); + fprintf(stderr, "At line %u: ", start_lineno); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); fflush(stderr); @@ -615,7 +628,7 @@ static void abort_not_supported_test() exit(62); } -static void verbose_msg(const char* fmt, ...) +static void verbose_msg(const char *fmt, ...) { va_list args; DBUG_ENTER("verbose_msg"); @@ -624,7 +637,7 @@ static void verbose_msg(const char* fmt, ...) va_start(args, fmt); - fprintf(stderr, "%s: At line %u: ", my_progname, start_lineno); + fprintf(stderr, "mysqltest: At line %u: ", start_lineno); vfprintf(stderr, fmt, args); fprintf(stderr, "\n"); va_end(args); @@ -634,12 +647,12 @@ static void verbose_msg(const char* fmt, ...) void init_parser() { - parser.current_line = parser.read_lines = 0; - memset(&var_reg,0, sizeof(var_reg)); + parser.current_line= parser.read_lines= 0; + memset(&var_reg, 0, sizeof(var_reg)); } -int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname) +int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) { MY_STAT stat_info; char *tmp, *res_ptr; @@ -706,7 +719,7 @@ err: DBUG_RETURN(res); } -static int check_result(DYNAMIC_STRING* ds, const char* fname, +static int check_result(DYNAMIC_STRING* ds, const char *fname, my_bool require_option) { int error = 0; @@ -735,7 +748,7 @@ static int check_result(DYNAMIC_STRING* ds, const char* fname, } -VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, +VAR* var_get(const char *var_name, const char** var_name_end, my_bool raw, my_bool ignore_not_existing) { int digit; @@ -748,7 +761,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, digit = *++var_name - '0'; if (digit < 0 || digit >= 10) { - const char* save_var_name = var_name, *end; + const char *save_var_name = var_name, *end; uint length; end = (var_name_end) ? *var_name_end : 0; while (my_isvar(charset_info,*var_name) && var_name != end) @@ -790,7 +803,7 @@ err: DBUG_RETURN(0); } -static VAR *var_obtain(const char* name, int len) +static VAR *var_obtain(const char *name, int len) { VAR* v; if ((v = (VAR*)hash_search(&var_hash, name, len))) @@ -827,9 +840,11 @@ int var_set(const char *var_name, const char *var_name_end, } -int open_file(const char* name) +int open_file(const char *name) { char buff[FN_REFLEN]; + DBUG_ENTER("open_file"); + DBUG_PRINT("enter", ("name: %s", name)); if (!test_if_hard_path(name)) { strxmov(buff, opt_basedir, name, NullS); @@ -837,19 +852,51 @@ int open_file(const char* name) } fn_format(buff,name,"","",4); - if (*cur_file && cur_file == file_stack_end) + if (cur_file == file_stack_end) die("Source directives are nesting too deep"); - if (!(*(cur_file+1) = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) - die(NullS); cur_file++; + if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) + { + cur_file--; + die("Could not open file %s", buff); + } + cur_file->file_name= my_strdup(buff, MYF(MY_FAE)); *++lineno=1; + DBUG_RETURN(0); +} - return 0; + +/* + Check for unexpected "junk" after the end of query + This is normally caused by missing delimiters +*/ + +int check_eol_junk(const char *eol) +{ + const char *p= eol; + DBUG_ENTER("check_eol_junk"); + DBUG_PRINT("enter", ("eol: %s", eol)); + /* Remove all spacing chars except new line */ + while (*p && my_isspace(charset_info, *p) && (*p != '\n')) + p++; + + /* Check for extra delimiter */ + if (*p && !strncmp(p, delimiter, delimiter_length)) + die("Extra delimiter \"%s\" found", delimiter); + + /* Allow trailing # comment */ + if (*p && *p != '#') + { + if (*p == '\n') + die("Missing delimiter"); + die("End of line junk detected: \"%s\"", p); + } + DBUG_RETURN(0); } /* ugly long name, but we are following the convention */ -int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) +int do_wait_for_slave_to_stop(struct st_query *q __attribute__((unused))) { MYSQL* mysql = &cur_con->mysql; for (;;) @@ -877,7 +924,7 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) return 0; } -int do_require_manager(struct st_query* a __attribute__((unused))) +int do_require_manager(struct st_query *query __attribute__((unused)) ) { if (!manager) abort_not_supported_test(); @@ -885,95 +932,121 @@ int do_require_manager(struct st_query* a __attribute__((unused))) } #ifndef EMBEDDED_LIBRARY -int do_server_start(struct st_query* q) +int do_server_start(struct st_query *q) { - return do_server_op(q,"start"); + return do_server_op(q, "start"); } -int do_server_stop(struct st_query* q) +int do_server_stop(struct st_query *q) { - return do_server_op(q,"stop"); + return do_server_op(q, "stop"); } -int do_server_op(struct st_query* q,const char* op) +int do_server_op(struct st_query *q, const char *op) { - char* p=q->first_argument; - char com_buf[256],*com_p; + char *p= q->first_argument; + char com_buf[256], *com_p; if (!manager) { die("Manager is not initialized, manager commands are not possible"); } - com_p=strmov(com_buf,op); - com_p=strmov(com_p,"_exec "); + com_p= strmov(com_buf,op); + com_p= strmov(com_p,"_exec "); if (!*p) - die("Missing server name in server_%s\n",op); - while (*p && !my_isspace(charset_info,*p)) + die("Missing server name in server_%s", op); + while (*p && !my_isspace(charset_info, *p)) *com_p++= *p++; - *com_p++=' '; - com_p=int10_to_str(manager_wait_timeout,com_p,10); - *com_p++ = '\n'; - *com_p=0; - if (mysql_manager_command(manager,com_buf,(int)(com_p-com_buf))) - die("Error in command: %s(%d)",manager->last_error,manager->last_errno); + *com_p++= ' '; + com_p= int10_to_str(manager_wait_timeout, com_p, 10); + *com_p++= '\n'; + *com_p= 0; + if (mysql_manager_command(manager, com_buf, (int)(com_p-com_buf))) + die("Error in command: %s(%d)", manager->last_error, manager->last_errno); while (!manager->eof) { - if (mysql_manager_fetch_line(manager,com_buf,sizeof(com_buf))) + if (mysql_manager_fetch_line(manager, com_buf, sizeof(com_buf))) die("Error fetching result line: %s(%d)", manager->last_error, manager->last_errno); } + q->last_argument= p; return 0; } #endif -int do_source(struct st_query* q) + +/* + Source and execute the given file + + SYNOPSIS + do_source() + query called command + + DESCRIPTION + source <file_name> + + Open the file <file_name> and execute it + +*/ + +int do_source(struct st_query *query) { - char* p=q->first_argument, *name; + char *p= query->first_argument, *name; if (!*p) - die("Missing file name in source\n"); - name = p; + die("Missing file name in source"); + name= p; while (*p && !my_isspace(charset_info,*p)) p++; - *p = 0; - + if (*p) + *p++= 0; + query->last_argument= p; + /* + If this file has already been sourced, dont source it again. + It's already available in the q_lines cache + */ + if (parser.current_line < (parser.read_lines - 1)) + return 0; return open_file(name); } + /* Execute given command. SYNOPSIS do_exec() - q called command + query called command DESCRIPTION - If one uses --exec command [args] command in .test file - we will execute the command and record its output. + exec <command> + + Execute the text between exec and end of line in a subprocess. + The error code returned from the subprocess is checked against the + expected error array, previously set with the --error command. + It can thus be used to execute a command that shall fail. - RETURN VALUES - 0 ok - 1 error */ -static void do_exec(struct st_query* q) +static void do_exec(struct st_query *query) { int error; - DYNAMIC_STRING *ds= NULL; /* Assign just to avoid warning */ + DYNAMIC_STRING *ds= NULL; DYNAMIC_STRING ds_tmp; char buf[1024]; FILE *res_file; - char *cmd= q->first_argument; + char *cmd= query->first_argument; DBUG_ENTER("do_exec"); while (*cmd && my_isspace(charset_info, *cmd)) cmd++; if (!*cmd) - die("Missing argument in exec\n"); + die("Missing argument in exec"); + query->last_argument= query->end; DBUG_PRINT("info", ("Executing '%s'", cmd)); - if (!(res_file= popen(cmd, "r")) && q->abort_on_error) - die("popen() failed\n"); + if (!(res_file= popen(cmd, "r")) && query->abort_on_error) + die("popen(\"%s\", \"r\") failed", cmd); if (disable_result_log) { @@ -985,7 +1058,7 @@ static void do_exec(struct st_query* q) } else { - if (q->record_file[0]) + if (query->record_file[0]) { init_dynamic_string(&ds_tmp, "", 16384, 65536); ds= &ds_tmp; @@ -1002,33 +1075,35 @@ static void do_exec(struct st_query* q) uint status= WEXITSTATUS(error), i; my_bool ok= 0; - if (q->abort_on_error) - die("At line %u: command \"%s\" failed", start_lineno, cmd); + if (query->abort_on_error) + die("command \"%s\" failed", cmd); DBUG_PRINT("info", ("error: %d, status: %d", error, status)); - for (i=0 ; (uint) i < q->expected_errors ; i++) + for (i= 0; i < query->expected_errors; i++) { DBUG_PRINT("info", ("error: %d, status: %d", error, status)); DBUG_PRINT("info", ("expected error: %d", - q->expected_errno[i].code.errnum)); - if ((q->expected_errno[i].type == ERR_ERRNO) && - (q->expected_errno[i].code.errnum == status)) + query->expected_errno[i].code.errnum)); + if ((query->expected_errno[i].type == ERR_ERRNO) && + (query->expected_errno[i].code.errnum == status)) + { ok= 1; - verbose_msg("At line %u: command \"%s\" failed with expected error: %d", - start_lineno, cmd, status); + verbose_msg("command \"%s\" failed with expected error: %d", + cmd, status); + } } if (!ok) - die("At line: %u: command \"%s\" failed with wrong error: %d", - start_lineno, cmd, status); + die("command \"%s\" failed with wrong error: %d", + cmd, status); } - else if (q->expected_errno[0].type == ERR_ERRNO && - q->expected_errno[0].code.errnum != 0) + else if (query->expected_errno[0].type == ERR_ERRNO && + query->expected_errno[0].code.errnum != 0) { /* Error code we wanted was != 0, i.e. not an expected success */ - die("At line: %u: command \"%s\" succeeded - should have failed with errno %d...", - start_lineno, cmd, q->expected_errno[0].code.errnum); + die("command \"%s\" succeeded - should have failed with errno %d...", + cmd, query->expected_errno[0].code.errnum); } if (!disable_result_log) @@ -1038,14 +1113,14 @@ static void do_exec(struct st_query* q) if (record) { - if (!q->record_file[0] && !result_file) - die("At line %u: Missing result file", start_lineno); + if (!query->record_file[0] && !result_file) + die("Missing result file"); if (!result_file) - str_to_file(q->record_file, ds->str, ds->length); + str_to_file(query->record_file, ds->str, ds->length); } - else if (q->record_file[0]) + else if (query->record_file[0]) { - error= check_result(ds, q->record_file, q->require_file); + error= check_result(ds, query->record_file, query->require_file); } if (ds == &ds_tmp) dynstr_free(&ds_tmp); @@ -1053,7 +1128,7 @@ static void do_exec(struct st_query* q) } -int var_query_set(VAR* v, const char* p, const char** p_end) +int var_query_set(VAR* v, const char *p, const char** p_end) { char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p)); MYSQL_RES *res; @@ -1104,19 +1179,27 @@ int var_query_set(VAR* v, const char* p, const char** p_end) return 0; } -void var_copy(VAR* dest, VAR* src) +void var_copy(VAR *dest, VAR *src) { - dest->int_val=src->int_val; - dest->int_dirty=src->int_dirty; + dest->int_val= src->int_val; + dest->int_dirty= src->int_dirty; + + /* Alloc/realloc data for str_val in dest */ if (dest->alloced_len < src->alloced_len && - !(dest->str_val=my_realloc(dest->str_val,src->alloced_len+1, - MYF(MY_WME)))) + !(dest->str_val= dest->str_val + ? my_realloc(dest->str_val, src->alloced_len, MYF(MY_WME)) + : my_malloc(src->alloced_len, MYF(MY_WME)))) die("Out of memory"); - dest->str_val_len=src->str_val_len; - memcpy(dest->str_val,src->str_val,src->str_val_len+1); + else + dest->alloced_len= src->alloced_len; + + /* Copy str_val data to dest */ + dest->str_val_len= src->str_val_len; + if (src->str_val_len) + memcpy(dest->str_val, src->str_val, src->str_val_len); } -int eval_expr(VAR* v, const char* p, const char** p_end) +int eval_expr(VAR* v, const char *p, const char** p_end) { VAR* vp; if (*p == '$') @@ -1157,29 +1240,58 @@ int eval_expr(VAR* v, const char* p, const char** p_end) return 1; } -int do_inc(struct st_query* q) + +enum enum_operator { - char* p=q->first_argument; - VAR* v; - v = var_get(p, 0, 1, 0); - v->int_val++; - v->int_dirty = 1; - return 0; -} + DO_DEC, + DO_INC +}; + +/* + Decrease or increase the value of a variable + + SYNOPSIS + do_modify_var() + query called command + name human readable name of operator + operator operation to perform on the var + + DESCRIPTION + dec $var_name + inc $var_name -int do_dec(struct st_query* q) +*/ + +int do_modify_var(struct st_query *query, const char *name, + enum enum_operator operator) { - char* p=q->first_argument; + const char *p= query->first_argument; VAR* v; - v = var_get(p, 0, 1, 0); - v->int_val--; - v->int_dirty = 1; + if (!*p) + die("Missing arguments to %s", name); + if (*p != '$') + die("First argument to %s must be a variable (start with $)", name); + v= var_get(p, &p, 1, 0); + switch (operator){ + case DO_DEC: + v->int_val--; + break; + case DO_INC: + v->int_val++; + break; + default: + die("Invalid operator to do_operator"); + break; + } + v->int_dirty= 1; + query->last_argument= (char*)++p; return 0; } -int do_system(struct st_query* q) + +int do_system(struct st_query *q) { - char* p=q->first_argument; + char *p=q->first_argument; VAR v; var_init(&v, 0, 0, 0, 0); eval_expr(&v, p, 0); /* NULL terminated */ @@ -1191,49 +1303,85 @@ int do_system(struct st_query* q) memcpy(expr_buf, v.str_val, v.str_val_len); expr_buf[v.str_val_len] = 0; DBUG_PRINT("info", ("running system command '%s'", expr_buf)); - if (system(expr_buf) && q->abort_on_error) - die("system command '%s' failed", expr_buf); + if (system(expr_buf)) + { + if (q->abort_on_error) + die("system command '%s' failed", expr_buf); + /* If ! abort_on_error, display message and continue */ + verbose_msg("system command '%s' failed", expr_buf); + } } + else + die("Missing arguments to system, nothing to do!"); var_free(&v); + q->last_argument= q->end; return 0; } -int do_echo(struct st_query* q) + +/* + Print the content between echo and <delimiter> to result file. + If content is a variable, the variable value will be retrieved + + SYNOPSIS + do_echo() + q called command + + DESCRIPTION + Usage 1: + echo text + Print the text after echo until end of command to result file + + Usage 2: + echo $<var_name> + Print the content of the variable <var_name> to result file + +*/ + +int do_echo(struct st_query *q) { - char* p=q->first_argument; + char *p= q->first_argument; + DYNAMIC_STRING *ds; + DYNAMIC_STRING ds_tmp; VAR v; var_init(&v,0,0,0,0); - eval_expr(&v, p, 0); /* NULL terminated */ - if (v.str_val_len) + + if (q->record_file[0]) { - fflush(stdout); - write(1, v.str_val, v.str_val_len); + init_dynamic_string(&ds_tmp, "", 256, 512); + ds= &ds_tmp; } - write(1, "\n", 1); + else + ds= &ds_res; + + eval_expr(&v, p, 0); /* NULL terminated */ + if (v.str_val_len) + dynstr_append_mem(ds, v.str_val, v.str_val_len); + dynstr_append_mem(ds, "\n", 1); var_free(&v); + if (ds == &ds_tmp) + dynstr_free(&ds_tmp); + q->last_argument= q->end; return 0; } -int do_sync_with_master2(const char* p) +int do_sync_with_master2(long offset) { MYSQL_RES* res; MYSQL_ROW row; - MYSQL* mysql = &cur_con->mysql; + MYSQL* mysql= &cur_con->mysql; char query_buf[FN_REFLEN+128]; - int offset= 0, tries= 0; + int tries= 0; int rpl_parse; if (!master_pos.file[0]) { die("Line %u: Calling 'sync_with_master' without calling 'save_master_pos'", start_lineno); } - rpl_parse = mysql_rpl_parse_enabled(mysql); + rpl_parse= mysql_rpl_parse_enabled(mysql); mysql_disable_rpl_parse(mysql); - if (*p) - offset = atoi(p); - sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file, master_pos.pos + offset); @@ -1243,10 +1391,10 @@ wait_for_position: die("line %u: failed in %s: %d: %s", start_lineno, query_buf, mysql_errno(mysql), mysql_error(mysql)); - if (!(last_result = res = mysql_store_result(mysql))) + if (!(last_result= res= mysql_store_result(mysql))) die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno, query_buf); - if (!(row = mysql_fetch_row(res))) + if (!(row= mysql_fetch_row(res))) die("line %u: empty result in %s", start_lineno, query_buf); if (!row[0]) { @@ -1271,9 +1419,21 @@ wait_for_position: return 0; } -int do_sync_with_master(struct st_query* q) +int do_sync_with_master(struct st_query *query) { - return do_sync_with_master2(q->first_argument); + long offset= 0; + char *p= query->first_argument; + const char *offset_start= p; + if (*offset_start) + { + for (; my_isdigit(charset_info, *p); p++) + offset = offset * 10 + *p - '0'; + + if(*p && !my_isspace(charset_info, *p)) + die("Invalid integer argument \"%s\"", offset_start); + query->last_argument= p; + } + return do_sync_with_master2(offset); } int do_save_master_pos() @@ -1288,7 +1448,7 @@ int do_save_master_pos() mysql_disable_rpl_parse(mysql); if (mysql_query(mysql, query= "show master status")) - die("At line %u: failed in show master status: %d: %s", start_lineno, + die("failed in show master status: %d: %s", mysql_errno(mysql), mysql_error(mysql)); if (!(last_result =res = mysql_store_result(mysql))) @@ -1307,21 +1467,51 @@ int do_save_master_pos() } -int do_let(struct st_query* q) +/* + Assign the variable <var_name> with <var_val> + + SYNOPSIS + do_let() + query called command + + DESCRIPTION + let $<var_name>=<var_val><delimiter> + + <var_name> - is the string string found between the $ and = + <var_val> - is the content between the = and <delimiter>, it may span + multiple line and contain any characters except <delimiter> + <delimiter> - is a string containing of one or more chars, default is ; + + RETURN VALUES + Program will die if error detected +*/ + +int do_let(struct st_query *query) { - char* p=q->first_argument; + char *p= query->first_argument; char *var_name, *var_name_end, *var_val_start; + + /* Find <var_name> */ if (!*p) - die("Missing variable name in let\n"); - var_name = p; - while (*p && (*p != '=' || my_isspace(charset_info,*p))) + die("Missing arguments to let"); + var_name= p; + while (*p && (*p != '=') && !my_isspace(charset_info,*p)) + p++; + var_name_end= p; + if (var_name+1 == var_name_end) + die("Missing variable name in let"); + while (my_isspace(charset_info,*p)) p++; - var_name_end = p; - if (*p == '=') p++; + if (*p++ != '=') + die("Missing assignment operator in let"); + + /* Find start of <var_val> */ while (*p && my_isspace(charset_info,*p)) p++; - var_val_start = p; - return var_set(var_name, var_name_end, var_val_start, q->end); + var_val_start= p; + query->last_argument= query->end; + /* Assign var_val to var_name */ + return var_set(var_name, var_name_end, var_val_start, query->end); } @@ -1340,7 +1530,7 @@ int var_set_errno(int sql_errno) } -int do_rpl_probe(struct st_query* q __attribute__((unused))) +int do_rpl_probe(struct st_query *query __attribute__((unused))) { DBUG_ENTER("do_rpl_probe"); if (mysql_rpl_probe(&cur_con->mysql)) @@ -1349,71 +1539,104 @@ int do_rpl_probe(struct st_query* q __attribute__((unused))) } -int do_enable_rpl_parse(struct st_query* q __attribute__((unused))) +int do_enable_rpl_parse(struct st_query *query __attribute__((unused))) { mysql_enable_rpl_parse(&cur_con->mysql); return 0; } -int do_disable_rpl_parse(struct st_query* q __attribute__((unused))) +int do_disable_rpl_parse(struct st_query *query __attribute__((unused))) { mysql_disable_rpl_parse(&cur_con->mysql); return 0; } -int do_sleep(struct st_query* q, my_bool real_sleep) +/* + Sleep the number of specifed seconds + + SYNOPSIS + do_sleep() + q called command + real_sleep use the value from opt_sleep as number of seconds to sleep + + DESCRIPTION + sleep <seconds> + real_sleep + +*/ + +int do_sleep(struct st_query *query, my_bool real_sleep) { - char *p=q->first_argument; - while (*p && my_isspace(charset_info,*p)) + int error= 0; + char *p= query->first_argument; + char *sleep_start, *sleep_end= query->end; + double sleep_val; + + while (my_isspace(charset_info, *p)) p++; if (!*p) - die("Missing argument in sleep\n"); + die("Missing argument to sleep"); + sleep_start= p; + /* Check that arg starts with a digit, not handled by my_strtod */ + if (!my_isdigit(charset_info, *sleep_start)) + die("Invalid argument to sleep \"%s\"", query->first_argument); + sleep_val= my_strtod(sleep_start, &sleep_end, &error); + if (error) + die("Invalid argument to sleep \"%s\"", query->first_argument); + + /* Fixed sleep time selected by --sleep option */ if (opt_sleep && !real_sleep) - my_sleep(opt_sleep * 1000000L); - else - my_sleep((ulong) (atof(p) * 1000000L)); + sleep_val= opt_sleep; + + my_sleep((ulong) (sleep_val * 1000000L)); + query->last_argument= sleep_end; return 0; } -static void get_file_name(char *filename, struct st_query* q) +static void get_file_name(char *filename, struct st_query *q) { - char* p=q->first_argument; - strnmov(filename, p, FN_REFLEN); - /* Remove end space */ - while (p > filename && my_isspace(charset_info,p[-1])) - p--; - p[0]=0; + char *p= q->first_argument, *name; + if (!*p) + die("Missing file name argument"); + name= p; + while (*p && !my_isspace(charset_info,*p)) + p++; + if (*p) + *p++= 0; + q->last_argument= p; + strmake(filename, name, FN_REFLEN); } -static void set_charset(struct st_query* q) +static void set_charset(struct st_query *q) { - char* charset_name= q->first_argument; - char* tmp; + char *charset_name= q->first_argument; + char *p; if (!charset_name || !*charset_name) - die("Missing charset name in 'character_set'\n"); + die("Missing charset name in 'character_set'"); /* Remove end space */ - tmp= charset_name; - while (*tmp && !my_isspace(charset_info,*tmp)) - tmp++; - *tmp= 0; - + p= charset_name; + while (*p && !my_isspace(charset_info,*p)) + p++; + if(*p) + *p++= 0; + q->last_argument= p; charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); if (!charset_info) abort_not_supported_test(); } -static uint get_errcodes(match_err *to,struct st_query* q) +static uint get_errcodes(match_err *to,struct st_query *q) { - char* p= q->first_argument; + char *p= q->first_argument; uint count= 0; DBUG_ENTER("get_errcodes"); if (!*p) - die("Missing argument in %s\n", q->query); + die("Missing argument in %s", q->query); do { @@ -1447,20 +1670,20 @@ static uint get_errcodes(match_err *to,struct st_query* q) } } if (!e->name) - die("Unknown SQL error '%s'\n", start); + die("Unknown SQL error '%s'", start); } else { long val; if (!(p= str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val))) - die("Invalid argument in %s\n", q->query); + die("Invalid argument in %s", q->query); to[count].code.errnum= (uint) val; to[count].type= ERR_ERRNO; } count++; } while (*(p++) == ','); - + q->last_argument= (p - 1); to[count].type= ERR_EMPTY; /* End of data */ DBUG_RETURN(count); } @@ -1474,7 +1697,7 @@ static uint get_errcodes(match_err *to,struct st_query* q) static char *get_string(char **to_ptr, char **from_ptr, - struct st_query* q) + struct st_query *q) { reg1 char c,sep; char *to= *to_ptr, *from= *from_ptr, *start=to; @@ -1522,7 +1745,7 @@ static char *get_string(char **to_ptr, char **from_ptr, *to++=c; } if (*from != ' ' && *from) - die("Wrong string argument in %s\n", q->query); + die("Wrong string argument in %s", q->query); while (my_isspace(charset_info,*from)) /* Point to next string */ from++; @@ -1557,7 +1780,7 @@ static char *get_string(char **to_ptr, char **from_ptr, static void get_replace(struct st_query *q) { uint i; - char *from=q->first_argument; + char *from= q->first_argument; char *buff,*start; char word_end_chars[256],*pos; POINTER_ARRAY to_array,from_array; @@ -1568,14 +1791,14 @@ static void get_replace(struct st_query *q) bzero((char*) &to_array,sizeof(to_array)); bzero((char*) &from_array,sizeof(from_array)); if (!*from) - die("Missing argument in %s\n", q->query); + die("Missing argument in %s", q->query); start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); while (*from) { char *to=buff; to=get_string(&buff, &from, q); if (!*from) - die("Wrong number of arguments to replace in %s\n", q->query); + die("Wrong number of arguments to replace_result in '%s'", q->query); insert_pointer_name(&from_array,to); to=get_string(&buff, &from, q); insert_pointer_name(&to_array,to); @@ -1589,10 +1812,11 @@ static void get_replace(struct st_query *q) (uint) from_array.typelib.count, word_end_chars)) || initialize_replace_buffer()) - die("Can't initialize replace from %s\n", q->query); + die("Can't initialize replace from '%s'", q->query); free_pointer_array(&from_array); free_pointer_array(&to_array); my_free(start, MYF(0)); + q->last_argument= q->end; DBUG_VOID_RETURN; } @@ -1608,25 +1832,18 @@ void free_replace() DBUG_VOID_RETURN; } -int select_connection(char *p) + +int select_connection_name(const char *name) { - char* name; struct connection *con; - DBUG_ENTER("select_connection"); - DBUG_PRINT("enter",("name: '%s'",p)); + DBUG_ENTER("select_connection2"); + DBUG_PRINT("enter",("name: '%s'", name)); - if (!*p) - die("Missing connection name in connect\n"); - name = p; - while (*p && !my_isspace(charset_info,*p)) - p++; - *p = 0; - - for (con = cons; con < next_con; con++) + for (con= cons; con < next_con; con++) { if (!strcmp(con->name, name)) { - cur_con = con; + cur_con= con; DBUG_RETURN(0); } } @@ -1634,21 +1851,42 @@ int select_connection(char *p) DBUG_RETURN(1); /* Never reached */ } -int close_connection(struct st_query* q) + +int select_connection(struct st_query *query) +{ + char *name; + char *p= query->first_argument; + DBUG_ENTER("select_connection"); + + if (!*p) + die("Missing connection name in connect"); + name= p; + while (*p && !my_isspace(charset_info,*p)) + p++; + if (*p) + *p++= 0; + query->last_argument= p; + return select_connection_name(name); +} + + +int close_connection(struct st_query *q) { - char* p=q->first_argument, *name; + char *p= q->first_argument, *name; struct connection *con; DBUG_ENTER("close_connection"); DBUG_PRINT("enter",("name: '%s'",p)); if (!*p) - die("Missing connection name in connect\n"); - name = p; + die("Missing connection name in connect"); + name= p; while (*p && !my_isspace(charset_info,*p)) p++; - *p = 0; - for (con = cons; con < next_con; con++) + if (*p) + *p++= 0; + q->last_argument= p; + for (con= cons; con < next_con; con++) { if (!strcmp(con->name, name)) { @@ -1678,21 +1916,21 @@ int close_connection(struct st_query* q) ) are delimiters/terminators */ -char* safe_get_param(char* str, char** arg, const char* msg) +char* safe_get_param(char *str, char** arg, const char *msg) { DBUG_ENTER("safe_get_param"); while (*str && my_isspace(charset_info,*str)) str++; - *arg = str; + *arg= str; for (; *str && *str != ',' && *str != ')' ; str++) { if (my_isspace(charset_info,*str)) - *str = 0; + *str= 0; } if (!*str) die(msg); - *str++ = 0; + *str++= 0; DBUG_RETURN(str); } @@ -1732,16 +1970,16 @@ void init_manager() 0 - success, non-0 - failure */ -int safe_connect(MYSQL* con, const char* host, const char* user, - const char* pass, - const char* db, int port, const char* sock) +int safe_connect(MYSQL* con, const char *host, const char *user, + const char *pass, + const char *db, int port, const char *sock) { int con_error = 1; int i; for (i = 0; i < MAX_CON_TRIES; ++i) { if (mysql_real_connect(con, host,user, pass, db, port, sock, - CLIENT_MULTI_STATEMENTS)) + CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) { con_error = 0; break; @@ -1856,7 +2094,7 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, if (record) { if (!q->record_file[0] && !result_file) - die("At line %u: Missing result file", start_lineno); + die("Missing result file"); if (!result_file) str_to_file(q->record_file, ds->str, ds->length); } @@ -1871,14 +2109,14 @@ err: } -int do_connect(struct st_query* q) +int do_connect(struct st_query *q) { - char* con_name, *con_user,*con_pass, *con_host, *con_port_str, + char *con_name, *con_user,*con_pass, *con_host, *con_port_str, *con_db, *con_sock; - char* p=q->first_argument; + char *p= q->first_argument; char buff[FN_REFLEN]; int con_port; - int free_con_sock = 0; + int free_con_sock= 0; int error= 0; int create_conn= 1; @@ -1888,40 +2126,41 @@ int do_connect(struct st_query* q) if (*p != '(') die("Syntax error in connect - expected '(' found '%c'", *p); p++; - p = safe_get_param(p, &con_name, "missing connection name"); - p = safe_get_param(p, &con_host, "missing connection host"); - p = safe_get_param(p, &con_user, "missing connection user"); - p = safe_get_param(p, &con_pass, "missing connection password"); - p = safe_get_param(p, &con_db, "missing connection db"); + p= safe_get_param(p, &con_name, "missing connection name"); + p= safe_get_param(p, &con_host, "missing connection host"); + p= safe_get_param(p, &con_user, "missing connection user"); + p= safe_get_param(p, &con_pass, "missing connection password"); + p= safe_get_param(p, &con_db, "missing connection db"); if (!*p || *p == ';') /* Default port and sock */ { - con_port=port; - con_sock=(char*) unix_sock; + con_port= port; + con_sock= (char*) unix_sock; } else { VAR* var_port, *var_sock; - p = safe_get_param(p, &con_port_str, "missing connection port"); + p= safe_get_param(p, &con_port_str, "missing connection port"); if (*con_port_str == '$') { - if (!(var_port = var_get(con_port_str, 0, 0, 0))) + if (!(var_port= var_get(con_port_str, 0, 0, 0))) die("Unknown variable '%s'", con_port_str+1); - con_port = var_port->int_val; + con_port= var_port->int_val; } else - con_port=atoi(con_port_str); - p = safe_get_param(p, &con_sock, "missing connection socket"); + con_port= atoi(con_port_str); + p= safe_get_param(p, &con_sock, "missing connection socket"); if (*con_sock == '$') { - if (!(var_sock = var_get(con_sock, 0, 0, 0))) + if (!(var_sock= var_get(con_sock, 0, 0, 0))) die("Unknown variable '%s'", con_sock+1); - if (!(con_sock = (char*)my_malloc(var_sock->str_val_len+1, MYF(0)))) + if (!(con_sock= (char*)my_malloc(var_sock->str_val_len+1, MYF(0)))) die("Out of memory"); - free_con_sock = 1; + free_con_sock= 1; memcpy(con_sock, var_sock->str_val, var_sock->str_val_len); - con_sock[var_sock->str_val_len] = 0; + con_sock[var_sock->str_val_len]= 0; } } + q->last_argument= p; if (next_con == cons_end) die("Connection limit exhausted - increase MAX_CONS in mysqltest.c"); @@ -1941,11 +2180,10 @@ int do_connect(struct st_query* q) if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR) con_sock=fn_format(buff, con_sock, TMPDIR, "",0); if (!con_db[0]) - con_db=db; + con_db= db; /* Special database to allow one to connect without a database name */ if (con_db && !strcmp(con_db,"*NO-ONE*")) - con_db=0; - + con_db= 0; if (q->abort_on_error) { if ((safe_connect(&next_con->mysql, con_host, con_user, con_pass, @@ -1970,14 +2208,15 @@ int do_connect(struct st_query* q) } -int do_done(struct st_query* q) +int do_done(struct st_query *q) { - /* Dummy statement to eliminate compiler warning */ - q->type = Q_END_BLOCK; - /* Check if empty block stack */ if (cur_block == block_stack) + { + if (*q->query != '}') + die("Stray 'end' command - end of block before beginning"); die("Stray '}' - end of block before beginning"); + } /* Test if inner block has been executed */ if (cur_block->ok && cur_block->cmd == cmd_while) @@ -1998,9 +2237,10 @@ int do_done(struct st_query* q) int do_block(enum block_cmd cmd, struct st_query* q) { - char* p=q->first_argument; - const char* expr_start, *expr_end; + char *p= q->first_argument; + const char *expr_start, *expr_end; VAR v; + const char *cmd_name= (cmd == cmd_while ? "while" : "if"); /* Check stack overflow */ if (cur_block == block_stack_end) @@ -2020,12 +2260,21 @@ int do_block(enum block_cmd cmd, struct st_query* q) } /* Parse and evaluate test expression */ - expr_start = strchr(p, '('); + expr_start= strchr(p, '('); if (!expr_start) - die("missing '(' in while"); - expr_end = strrchr(expr_start, ')'); + die("missing '(' in %s", cmd_name); + expr_end= strrchr(expr_start, ')'); if (!expr_end) - die("missing ')' in while"); + die("missing ')' in %s", cmd_name); + p= (char*)expr_end+1; + + while (*p && my_isspace(charset_info, *p)) + p++; + if (*p == '{') + die("Missing newline between %s and '{'", cmd_name); + if (*p) + die("Missing '{' after %s. Found \"%s\"", cmd_name, p); + var_init(&v,0,0,0,0); eval_expr(&v, ++expr_start, &expr_end); @@ -2071,7 +2320,7 @@ my_bool end_of_query(int c) return 0; for (i= 1; i < delimiter_length && - (c= my_getc(*cur_file)) == *(delimiter + i); + (c= my_getc(cur_file->file)) == *(delimiter + i); i++) tmp[i]= c; @@ -2086,11 +2335,35 @@ my_bool end_of_query(int c) } -int read_line(char* buf, int size) +/* + Read one "line" from the file + + SYNOPSIS + read_line + buf buffer for the read line + size size of the buffer i.e max size to read + + DESCRIPTION + This function actually reads several lines an adds them to the + buffer buf. It will continue to read until it finds what it believes + is a complete query. + + Normally that means it will read lines until it reaches the + "delimiter" that marks end of query. Default delimiter is ';' + The function should be smart enough not to detect delimiter's + found inside strings sorrounded with '"' and '\'' escaped strings. + + If the first line in a query starts with '#' or '-' this line is treated + as a comment. A comment is always terminated when end of line '\n' is + reached. + +*/ + +int read_line(char *buf, int size) { int c; char quote; - char* p= buf, *buf_end= buf + size - 1; + 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; @@ -2100,19 +2373,30 @@ int read_line(char* buf, int size) for (; p < buf_end ;) { no_save= 0; - c= my_getc(*cur_file); - if (feof(*cur_file)) + c= my_getc(cur_file->file); + if (feof(cur_file->file)) { found_eof: - if ((*cur_file) != stdin) - my_fclose(*cur_file, MYF(0)); - cur_file--; + if (cur_file->file != stdin) + my_fclose(cur_file->file, MYF(0)); + my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR)); + cur_file->file_name= 0; lineno--; + start_lineno= *lineno; if (cur_file == file_stack) { + /* We're back at the first file, check if + all { have matching } + */ + if (cur_block != block_stack) + { + start_lineno= *(lineno+1); + die("Missing end of block"); + } DBUG_PRINT("info", ("end of file")); DBUG_RETURN(1); } + cur_file--; continue; } @@ -2146,7 +2430,8 @@ int read_line(char* buf, int size) } break; case R_LINE_START: - if (c == '#' || c == '-' || parsing_disabled) + /* Only accept start of comment if this is the first line in query */ + if ((*lineno == start_lineno) && (c == '#' || c == '-' || parsing_disabled)) { state = R_COMMENT; } @@ -2216,9 +2501,9 @@ int read_line(char* buf, int size) for (i= 1; i < charlen; i++) { - if (feof(*cur_file)) + if (feof(cur_file->file)) goto found_eof; /* FIXME: could we just break here?! */ - c= my_getc(*cur_file); + c= my_getc(cur_file->file); *p++ = c; } if (! my_ismbchar(charset_info, mb_start, p)) @@ -2235,15 +2520,34 @@ int read_line(char* buf, int size) } } *p= 0; /* Always end with \0 */ - DBUG_RETURN(feof(*cur_file)); + DBUG_RETURN(feof(cur_file->file)); } +/* + Create a query from a set of lines + + SYNOPSIS + read_query() + q_ptr pointer where to return the new query + + DESCRIPTION + Converts lines returned by read_line into a query, this involves + parsing the first word in the read line to find the query type. + + + A -- comment may contain a valid query as the first word after the + comment start. Thus it's always checked to see if that is the case. + The advantage with this approach is to be able to execute commands + terminated by new line '\n' regardless how many "delimiter" it contain. + + If query starts with @<file_name> this will specify a file to .... +*/ static char read_query_buf[MAX_QUERY]; int read_query(struct st_query** q_ptr) { - char *p = read_query_buf, * p1 ; + char *p= read_query_buf, *p1; struct st_query* q; DBUG_ENTER("read_query"); @@ -2260,16 +2564,16 @@ int read_query(struct st_query** q_ptr) q->require_file= 0; q->first_word_len= 0; - q->type = Q_UNKNOWN; + q->type= Q_UNKNOWN; q->query_buf= q->query= 0; if (read_line(read_query_buf, sizeof(read_query_buf))) { DBUG_RETURN(1); } - DBUG_PRINT("info", ("query: %s", read_query_buf)); + DBUG_PRINT("info", ("query: %s", read_query_buf)); if (*p == '#') { - q->type = Q_COMMENT; + q->type= Q_COMMENT; /* This goto is to avoid losing the "expected error" info. */ goto end; } @@ -2279,8 +2583,6 @@ int read_query(struct st_query** q_ptr) sizeof(global_expected_errno)); q->expected_errors= global_expected_errors; q->abort_on_error= (global_expected_errors == 0 && abort_on_error); - bzero((gptr) global_expected_errno, sizeof(global_expected_errno)); - global_expected_errors=0; } if (p[0] == '-' && p[1] == '-') @@ -2290,34 +2592,6 @@ int read_query(struct st_query** q_ptr) } else if (!parsing_disabled) { - if (*p == '!') - { - q->abort_on_error= 0; - p++; - if (*p == '$') - { - int expected_errno= 0; - p++; - for (; my_isdigit(charset_info, *p); p++) - expected_errno = expected_errno * 10 + *p - '0'; - q->expected_errno[0].code.errnum = expected_errno; - q->expected_errno[0].type= ERR_ERRNO; - q->expected_errno[1].type= ERR_EMPTY; - q->expected_errors=1; - } - else if (*p == 'S') /* SQLSTATE */ - { - int i; - p++; - for (i = 0; my_isalnum(charset_info, *p) && i < SQLSTATE_LENGTH; p++, i++) - q->expected_errno[0].code.sqlstate[i]= *p; - q->expected_errno[0].code.sqlstate[i]= '\0'; - q->expected_errno[0].type= ERR_SQLSTATE; - q->expected_errno[1].type= ERR_EMPTY; - q->expected_errors=1; - } - } - while (*p && my_isspace(charset_info, *p)) p++ ; if (*p == '@') @@ -2478,7 +2752,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), argument= buff; } fn_format(buff, argument, "", "", 4); - if (!(*++cur_file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) + DBUG_ASSERT(cur_file->file == 0); + if (!(cur_file->file= + my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(MY_WME)))) die("Could not open %s: errno = %d", argument, errno); break; } @@ -2564,7 +2840,7 @@ int parse_args(int argc, char **argv) return 0; } -char* safe_str_append(char* buf, const char* str, int size) +char* safe_str_append(char *buf, const char *str, int size) { int i,c ; for (i = 0; (c = *str++) && i < size - 1; i++) @@ -2573,7 +2849,7 @@ char* safe_str_append(char* buf, const char* str, int size) return buf; } -void str_to_file(const char* fname, char* str, int size) +void str_to_file(const char *fname, char *str, int size) { int fd; char buff[FN_REFLEN]; @@ -2592,7 +2868,7 @@ void str_to_file(const char* fname, char* str, int size) my_close(fd, MYF(0)); } -void reject_dump(const char* record_file, char* buf, int size) +void reject_dump(const char *record_file, char *buf, int size) { char reject_file[FN_REFLEN]; str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size); @@ -2608,7 +2884,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, { len=(int) replace_strings(glob_replace, &out_buff, &out_length, val); if (len == -1) - die("Out of memory in replace\n"); + die("Out of memory in replace"); val=out_buff; } dynstr_append_mem(ds, val, len); @@ -2747,8 +3023,8 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) { got_error_on_send= mysql_send_query(mysql, query, query_len); if (got_error_on_send && q->expected_errno[0].type == ERR_EMPTY) - die("At line %u: unable to send query '%s' (mysql_errno=%d , errno=%d)", - start_lineno, query, mysql_errno(mysql), errno); + die("unable to send query '%s' (mysql_errno=%d , errno=%d)", + query, mysql_errno(mysql), errno); } do @@ -2826,7 +3102,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) warn_res= mysql_store_result(mysql); } if (!warn_res) - verbose_msg("Warning count is %u but didn't get any warnings\n", + verbose_msg("Warning count is %u but didn't get any warnings", count); else { @@ -2852,7 +3128,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) if (record) { if (!q->record_file[0] && !result_file) - die("At line %u: Missing result file", start_lineno); + die("Missing result file"); if (!result_file) str_to_file(q->record_file, ds->str, ds->length); } @@ -2917,7 +3193,7 @@ static int normal_handle_error(const char *query, struct st_query *q, abort_not_supported_test(); if (q->abort_on_error) - die("At line %u: query '%s' failed: %d: %s", start_lineno, query, + die("query '%s' failed: %d: %s", query, mysql_errno(mysql), mysql_error(mysql)); else { @@ -3044,7 +3320,7 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) may be a new connection. */ if (!(stmt= mysql_stmt_init(mysql))) - die("At line %u: unable init stmt structure"); + die("unable init stmt structure"); if (q->type != Q_EVAL) { @@ -3088,9 +3364,9 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) { if (q->abort_on_error) { - die("At line %u: unable to prepare statement '%s': " + die("unable to prepare statement '%s': " "%s (mysql_stmt_errno=%d returned=%d)", - start_lineno, query, + query, mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); } else @@ -3123,9 +3399,9 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) if (q->abort_on_error) { /* We got an error, unexpected */ - die("At line %u: unable to execute statement '%s': " + die("unable to execute statement '%s': " "%s (mysql_stmt_errno=%d returned=%d)", - start_lineno, query, mysql_stmt_error(stmt), + query, mysql_stmt_error(stmt), mysql_stmt_errno(stmt), got_error_on_execute); } else @@ -3145,9 +3421,9 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) my_bool one= 1; if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one) != 0) - die("At line %u: unable to set stmt attribute " + die("unable to set stmt attribute " "'STMT_ATTR_UPDATE_MAX_LENGTH': %s (returned=%d)", - start_lineno, query, err); + query, err); } /* @@ -3159,9 +3435,9 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) if (q->abort_on_error) { /* We got an error, unexpected */ - die("At line %u: unable to execute statement '%s': " + die("unable to execute statement '%s': " "%s (mysql_stmt_errno=%d returned=%d)", - start_lineno, query, mysql_stmt_error(stmt), + query, mysql_stmt_error(stmt), mysql_stmt_errno(stmt), got_error_on_execute); } else @@ -3251,18 +3527,18 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) /* Fill in the data into the structures created above */ if ((err= mysql_stmt_bind_result(stmt, bind)) != 0) - die("At line %u: unable to bind result to statement '%s': " + die("unable to bind result to statement '%s': " "%s (mysql_stmt_errno=%d returned=%d)", - start_lineno, query, + query, mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); /* Read result from each row */ for (row_idx= 0; row_idx < num_rows; row_idx++) { if ((err= mysql_stmt_fetch(stmt)) != 0) - die("At line %u: unable to fetch all rows from statement '%s': " + die("unable to fetch all rows from statement '%s': " "%s (mysql_stmt_errno=%d returned=%d)", - start_lineno, query, + query, mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); /* Read result from each column */ @@ -3300,9 +3576,9 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) } if ((err= mysql_stmt_fetch(stmt)) != MYSQL_NO_DATA) - die("At line %u: fetch didn't end with MYSQL_NO_DATA from statement " + die("fetch didn't end with MYSQL_NO_DATA from statement " "'%s': %s (mysql_stmt_errno=%d returned=%d)", - start_lineno, query, + query, mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); free_replace_column(); @@ -3339,7 +3615,7 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) if (record) { if (!q->record_file[0] && !result_file) - die("At line %u: Missing result file", start_lineno); + die("Missing result file"); if (!result_file) str_to_file(q->record_file, ds->str, ds->length); } @@ -3444,7 +3720,7 @@ static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds) { MYSQL_RES *warn_res= mysql_store_result(mysql); if (!warn_res) - verbose_msg("Warning count is %u but didn't get any warnings\n", + verbose_msg("Warning count is %u but didn't get any warnings", count); else { @@ -3467,7 +3743,7 @@ static int run_query_stmt_handle_error(char *query, struct st_query *q, } if (q->abort_on_error) - die("At line %u: query '%s' failed: %d: %s", start_lineno, query, + die("query '%s' failed: %d: %s", query, mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); else { @@ -3726,14 +4002,14 @@ int main(int argc, char **argv) memset(file_stack, 0, sizeof(file_stack)); memset(&master_pos, 0, sizeof(master_pos)); - file_stack_end = file_stack + MAX_INCLUDE_DEPTH; - cur_file = file_stack; + file_stack_end= file_stack + MAX_INCLUDE_DEPTH - 1; + cur_file= file_stack; lineno = lineno_stack; my_init_dynamic_array(&q_lines, sizeof(struct st_query*), INIT_Q_LINES, INIT_Q_LINES); memset(block_stack, 0, sizeof(block_stack)); - block_stack_end= block_stack + BLOCK_STACK_DEPTH; + block_stack_end= block_stack + BLOCK_STACK_DEPTH - 1; cur_block= block_stack; cur_block->ok= TRUE; /* Outer block should always be executed */ cur_block->cmd= cmd_none; @@ -3747,7 +4023,11 @@ int main(int argc, char **argv) (char**) embedded_server_groups)) die("Can't initialize MySQL server"); if (cur_file == file_stack) - *++cur_file = stdin; + { + DBUG_ASSERT(cur_file->file == 0); + cur_file->file= stdin; + cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME)); + } *lineno=1; #ifndef EMBEDDED_LIBRARY if (manager_host) @@ -3793,19 +4073,20 @@ int main(int argc, char **argv) get_query_type(q); if (cur_block->ok) { + q->last_argument= q->first_argument; processed = 1; switch (q->type) { case Q_CONNECT: error|= do_connect(q); break; - case Q_CONNECTION: select_connection(q->first_argument); break; + case Q_CONNECTION: select_connection(q); break; case Q_DISCONNECT: case Q_DIRTY_CLOSE: close_connection(q); break; case Q_RPL_PROBE: do_rpl_probe(q); break; case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(q); break; case Q_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break; - case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; + case Q_ENABLE_QUERY_LOG: disable_query_log=0; break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break; case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break; case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break; @@ -3828,19 +4109,24 @@ int main(int argc, char **argv) case Q_SERVER_START: do_server_start(q); break; case Q_SERVER_STOP: do_server_stop(q); break; #endif - case Q_INC: do_inc(q); break; - case Q_DEC: do_dec(q); break; + case Q_INC: do_modify_var(q, "inc", DO_INC); break; + case Q_DEC: do_modify_var(q, "dec", DO_DEC); break; case Q_ECHO: do_echo(q); break; case Q_SYSTEM: do_system(q); break; case Q_DELIMITER: strmake(delimiter, q->first_argument, sizeof(delimiter) - 1); delimiter_length= strlen(delimiter); + q->last_argument= q->first_argument+delimiter_length; break; - case Q_DISPLAY_VERTICAL_RESULTS: display_result_vertically= TRUE; break; - case Q_DISPLAY_HORIZONTAL_RESULTS: - display_result_vertically= FALSE; break; + case Q_DISPLAY_VERTICAL_RESULTS: + display_result_vertically= TRUE; + break; + case Q_DISPLAY_HORIZONTAL_RESULTS: + display_result_vertically= FALSE; + break; case Q_LET: do_let(q); break; - case Q_EVAL_RESULT: eval_result = 1; break; + case Q_EVAL_RESULT: + eval_result = 1; break; case Q_EVAL: if (q->query == q->query_buf) { @@ -3873,6 +4159,7 @@ int main(int argc, char **argv) } error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND); display_result_vertically= old_display_result_vertically; + q->last_argument= q->end; break; } case Q_QUERY: @@ -3897,6 +4184,7 @@ int main(int argc, char **argv) save_file[0]=0; } error |= run_query(&cur_con->mysql, q, flags); + q->last_argument= q->end; break; } case Q_SEND: @@ -3916,6 +4204,7 @@ int main(int argc, char **argv) is given on this connection. */ error |= run_query(&cur_con->mysql, q, QUERY_SEND); + q->last_argument= q->end; break; case Q_RESULT: get_file_name(save_file,q); @@ -3940,22 +4229,20 @@ int main(int argc, char **argv) { do_save_master_pos(); if (*q->first_argument) - select_connection(q->first_argument); + select_connection(q); else - { - char buf[] = "slave"; - select_connection(buf); - } - do_sync_with_master2(""); + select_connection_name("slave"); + do_sync_with_master2(0); break; } case Q_COMMENT: /* Ignore row */ case Q_COMMENT_WITH_COMMAND: + q->last_argument= q->end; break; case Q_PING: (void) mysql_ping(&cur_con->mysql); break; - case Q_EXEC: + case Q_EXEC: do_exec(q); break; case Q_START_TIMER: @@ -3967,7 +4254,7 @@ int main(int argc, char **argv) timer_output(); got_end_timer= TRUE; break; - case Q_CHARACTER_SET: + case Q_CHARACTER_SET: set_charset(q); break; case Q_DISABLE_PS_PROTOCOL: @@ -4011,11 +4298,23 @@ int main(int argc, char **argv) default: current_line_inc = 1; break; } } + else + check_eol_junk(q->last_argument); + + if (q->type != Q_ERROR) + { + /* + As soon as any non "error" command has been executed, + the array with expected errors should be cleared + */ + global_expected_errors= 0; + bzero((gptr) global_expected_errno, sizeof(global_expected_errno)); + } parser.current_line += current_line_inc; } - if (result_file && ds_res.length) + if (result_file && ds_res.length && !error) { if (!record) error |= check_result(&ds_res, result_file, q->require_file); @@ -4874,7 +5173,7 @@ static void get_replace_column(struct st_query *q) free_replace_column(); if (!*from) - die("Missing argument in %s\n", q->query); + die("Missing argument in %s", q->query); /* Allocate a buffer for results */ start=buff=my_malloc(strlen(from)+1,MYF(MY_WME | MY_FAE)); @@ -4885,15 +5184,16 @@ static void get_replace_column(struct st_query *q) to= get_string(&buff, &from, q); if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS) - die("Wrong column number to replace_columns in %s\n", q->query); + die("Wrong column number to replace_column in '%s'", q->query); if (!*from) - die("Wrong number of arguments to replace in %s\n", q->query); + die("Wrong number of arguments to replace_column in '%s'", q->query); to= get_string(&buff, &from, q); my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR); replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE)); set_if_bigger(max_replace_column, column_number); } my_free(start, MYF(0)); + q->last_argument= q->end; } #if defined(__NETWARE__) || defined(__WIN__) @@ -4944,7 +5244,7 @@ static char *subst_env_var(const char *str) if (!(subst= getenv(env_var))) { my_free(result, MYF(0)); - die("MYSQLTEST.NLM: Environment variable %s is not defined\n", + die("MYSQLTEST.NLM: Environment variable %s is not defined", env_var); } diff --git a/configure.in b/configure.in index a0a394acaa0..5e006d1c169 100644 --- a/configure.in +++ b/configure.in @@ -1957,6 +1957,13 @@ AC_CACHE_CHECK([style of gethost* routines], mysql_cv_gethost_style, AC_LANG_SAVE AC_LANG_CPLUSPLUS +# Test whether madvise() is declared in C++ code -- it is not on some +# systems, such as Solaris +AC_CHECK_DECLS(madvise, [], [], [#if HAVE_SYS_MMAN_H +#include <sys/types.h> +#include <sys/mman.h> +#endif]) + # Do not treat warnings as errors if we are linking against other libc # this is to work around gcc not being permissive on non-system includes # with respect to ANSI C++ diff --git a/extra/yassl/src/socket_wrapper.cpp b/extra/yassl/src/socket_wrapper.cpp index 2252dfafdc5..91cea1f9753 100644 --- a/extra/yassl/src/socket_wrapper.cpp +++ b/extra/yassl/src/socket_wrapper.cpp @@ -93,11 +93,15 @@ void Socket::closeSocket() uint Socket::get_ready() const { - unsigned long ready = 0; - #ifdef _WIN32 + unsigned long ready = 0; ioctlsocket(socket_, FIONREAD, &ready); #else + /* + 64-bit Solaris requires the variable passed to + FIONREAD be a 32-bit value. + */ + int ready = 0; ioctl(socket_, FIONREAD, &ready); #endif diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 187d5cc6769..5a31510911e 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -96,6 +96,13 @@ public: #endif +// Disable assmebler when compiling with icc +// Temporary workaround for bug12717 +#if defined(__INTEL_COMPILER) + #define TAOCRYPT_DISABLE_X86ASM +#endif + + // CodeWarrior defines _MSC_VER #if !defined(TAOCRYPT_DISABLE_X86ASM) && ((defined(_MSC_VER) && \ diff --git a/include/my_alloc.h b/include/my_alloc.h index a3dd35d7ea3..1641b3acf3e 100644 --- a/include/my_alloc.h +++ b/include/my_alloc.h @@ -43,7 +43,7 @@ typedef struct st_mem_root unsigned int block_num; /* allocated blocks counter */ /* first free block in queue test counter (if it exceed - MAX_BLOCK_USAGE_BEFORE_DROP block will be droped in 'used' list) + MAX_BLOCK_USAGE_BEFORE_DROP block will be dropped in 'used' list) */ unsigned int first_block_usage; diff --git a/include/my_global.h b/include/my_global.h index ce9fa38041c..d240c5519d6 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -419,6 +419,10 @@ C_MODE_END #undef setrlimit #define setrlimit cma_setrlimit64 #endif +/* Declare madvise where it is not declared for C++, like Solaris */ +#if HAVE_MADVISE && !HAVE_DECL_MADVISE && defined(__cplusplus) +extern "C" int madvise(void *addr, size_t len, int behav); +#endif #ifdef __QNXNTO__ /* This has to be after include limits.h */ diff --git a/mysql-test/include/mysqltest_while.inc b/mysql-test/include/mysqltest_while.inc new file mode 100644 index 00000000000..90b05ee2695 --- /dev/null +++ b/mysql-test/include/mysqltest_while.inc @@ -0,0 +1,137 @@ +let $1 = 10; +while ($1) +{ +while ($1) +{ +while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + while ($1) +{ + echo $1; + dec $1; +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} +} diff --git a/mysql-test/include/windows.inc b/mysql-test/include/windows.inc new file mode 100644 index 00000000000..05ec7b0e021 --- /dev/null +++ b/mysql-test/include/windows.inc @@ -0,0 +1,4 @@ +--require r/true.require +disable_query_log; +select convert(@@version_compile_os using latin1) IN ("Win32","Win64","Windows") as "TRUE"; +enable_query_log; diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 1b6dcf0e7fc..d3b652186dd 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -183,7 +183,7 @@ sub spawn_impl ($$$$$$$$) { { if ( ! open(STDERR,$log_file_open_mode,$error) ) { - mtr_error("can't redirect STDERR to \"$output\": $!"); + mtr_error("can't redirect STDERR to \"$error\": $!"); } } } @@ -560,8 +560,8 @@ sub mtr_stop_mysqld_servers ($) { start_reap_all(); # Avoid zombies - SIGNAL: - mtr_kill_processes(\keys (%mysqld_pids)); + my @mysqld_pids= keys %mysqld_pids; + mtr_kill_processes(\@mysqld_pids); stop_reap_all(); # Get into control again diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 1e7a58cfd99..09d15f79198 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2484,6 +2484,11 @@ sub run_mysqltest ($) { mysqld_arguments($args,'master',0,$tinfo->{'master_opt'},[]); } + # ---------------------------------------------------------------------- + # export MYSQL_TEST variable containing <path>/mysqltest <args> + # ---------------------------------------------------------------------- + $ENV{'MYSQL_TEST'}= "$exe_mysqltest " . join(" ", @$args); + return mtr_run_test($exe,$args,$tinfo->{'path'},"",$path_timefile,""); } diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 5528f2b8a42..ba9a710390f 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -733,6 +733,7 @@ if [ x$USE_TIMER = x1 ] ; then fi MYSQL_TEST_BIN=$MYSQL_TEST MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS" +export MYSQL_TEST GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client GDB_MASTER_INIT=$MYSQL_TMP_DIR/gdbinit.master GDB_SLAVE_INIT=$MYSQL_TMP_DIR/gdbinit.slave diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 184bd07b066..7235fded66a 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -555,3 +555,6 @@ FROM t1 JOIN t2 ON t1.bID = t2.bID; COUNT(*) GROUP_CONCAT(DISTINCT t2.somename SEPARATOR ' |') 2 test DROP TABLE t1,t2; +select * from (select group_concat('c') from DUAL) t; +group_concat('c') +NULL diff --git a/mysql-test/r/grant2.result b/mysql-test/r/grant2.result index 7ac10de1f7c..ca375ef5057 100644 --- a/mysql-test/r/grant2.result +++ b/mysql-test/r/grant2.result @@ -312,3 +312,12 @@ flush privileges; drop database mysqltest_1; set password = password("changed"); ERROR 42000: Access denied for user ''@'localhost' to database 'mysql' +lock table mysql.user write; + flush privileges; + grant all on *.* to 'mysqltest_1'@'localhost'; +unlock tables; +lock table mysql.user write; + set password for 'mysqltest_1'@'localhost' = password(''); + revoke all on *.* from 'mysqltest_1'@'localhost'; +unlock tables; +drop user 'mysqltest_1'@'localhost'; diff --git a/mysql-test/r/lowercase_table.result b/mysql-test/r/lowercase_table.result index c09750ed561..7705961d08d 100644 --- a/mysql-test/r/lowercase_table.result +++ b/mysql-test/r/lowercase_table.result @@ -84,9 +84,3 @@ create table t2 like T1; drop table t1, t2; show tables; Tables_in_test -use lpt1; -ERROR 42000: Unknown database 'lpt1' -use com1; -ERROR 42000: Unknown database 'com1' -use prn; -ERROR 42000: Unknown database 'prn' diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index 256576704b5..1825e6f624f 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -7,18 +7,16 @@ otto select otto from (select 1 as otto) as t1; otto 1 +mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed: 1054: Unknown column 'friedrich' in 'field list' select friedrich from (select 1 as otto) as t1; ERROR 42S22: Unknown column 'friedrich' in 'field list' select otto from (select 1 as otto) as t1; otto 1 -select otto from (select 1 as otto) as t1; -otto -1 -select friedrich from (select 1 as otto) as t1; -ERROR 42S22: Unknown column 'friedrich' in 'field list' +mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22... select friedrich from (select 1 as otto) as t1; ERROR 42S22: Unknown column 'friedrich' in 'field list' +mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22 instead of 00000... select otto from (select 1 as otto) as t1; otto 1 @@ -135,6 +133,8 @@ ERROR 42S02: Table 'test.t1' doesn't exist select 1146 as "after_!errno_masked_error" ; after_!errno_masked_error 1146 +mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146 instead of 1000... +mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146 instead of 1000... garbage ; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 select 1064 as "after_--enable_abort_on_error" ; @@ -142,6 +142,219 @@ after_--enable_abort_on_error 1064 select 3 from t1 ; ERROR 42S02: Table 'test.t1' doesn't exist +mysqltest: At line 1: query 'select 3 from t1' failed with wrong errno 1146 instead of 1064... +mysqltest: At line 1: query 'select 3 from t1' failed: 1146: Table 'test.t1' doesn't exist +hello +hello +;;;;;;;; +# MySQL: -- The +mysqltest: At line 1: End of line junk detected: "6" +mysqltest: At line 1: End of line junk detected: "6" +mysqltest: At line 1: Missing delimiter +mysqltest: At line 1: Extra delimiter ";" found +MySQL +"MySQL" +MySQL: The world''s most popular open source database +"MySQL: The world's most popular open source database" +MySQL: The world''s +most popular open +source database +# MySQL: The world''s +# most popular open +# source database +- MySQL: The world''s +- most popular open +- source database +- MySQL: The world''s +-- most popular open +-- source database +# MySQL: The +--world''s +# most popular +-- open +- source database +"MySQL: The world's most popular; open source database" +"MySQL: The world's most popular ; open source database" +"MySQL: The world's most popular ;open source database" +echo message echo message + +mysqltest: At line 1: Empty variable +sh: -c: line 0: syntax error near unexpected token `;' +sh: -c: line 0: `;' +mysqltest: At line 1: command ";" failed +mysqltest: At line 1: Missing argument in exec +MySQL +"MySQL" +MySQL: The +world''s most +popular open +source database +# MySQL: The +# world''s most +# popular open +# source database +-- MySQL: The +-- world''s most +-- popular open +-- source database +# MySQL: The +- world''s most +-- popular open +# source database +'$message' +"$message" +hej +hej +hej +1 + + +a long variable content +a long variable content +a long $where variable content + +mysqltest: At line 1: Missing arguments to let +mysqltest: At line 1: Missing variable name in let +mysqltest: At line 1: Variable name in hi=hi does not start with '$' +mysqltest: At line 1: Missing assignment operator in let +mysqltest: At line 1: Missing assignment operator in let +mysqltest: At line 1: Missing arguments to let +mysqltest: At line 1: Missing variable name in let +mysqltest: At line 1: Variable name in =hi does not start with '$' +mysqltest: At line 1: Missing assignment operator in let +mysqltest: At line 1: Missing file name in source +mysqltest: At line 1: Could not open file ./non_existingFile +mysqltest: In included file "./var/tmp/recursive.sql": At line 1: Source directives are nesting too deep +mysqltest: In included file "./var/tmp/error.sql": At line 1: query 'garbage ' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'garbage' at line 1 + +2 = outer loop variable after while +here is the sourced script + +2 = outer loop variable before dec + +1 = outer loop variable after dec + +1 = outer loop variable after while +here is the sourced script + +1 = outer loop variable before dec + +0 = outer loop variable after dec + +2 = outer loop variable after while +here is the sourced script + +2 = outer loop variable before dec + +1 = outer loop variable after dec + +1 = outer loop variable after while +here is the sourced script + +1 = outer loop variable before dec + +0 = outer loop variable after dec + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script + +In loop +here is the sourced script +mysqltest: At line 1: Missing argument to sleep +mysqltest: At line 1: Invalid argument to sleep "abc" +1 +2 +101 +hej +1 +mysqltest: At line 1: Missing arguments to inc +mysqltest: At line 1: First argument to inc must be a variable (start with $) +mysqltest: At line 1: End of line junk detected: "1000" +4 +4 +-1 +-2 +99 +hej +-1 +mysqltest: At line 1: Missing arguments to dec +mysqltest: At line 1: First argument to dec must be a variable (start with $) +mysqltest: At line 1: End of line junk detected: "1000" +mysqltest: At line 1: Missing arguments to system, nothing to do! +mysqltest: At line 1: Missing arguments to system, nothing to do! +sh: NonExistsinfComamdn: command not found +mysqltest: At line 1: system command 'NonExistsinfComamdn' failed +test +test2 +test3 +test4 +1 +mysqltest: In included file "./include/mysqltest_while.inc": At line 64: Nesting too deeply +mysqltest: At line 1: missing '(' in while +mysqltest: At line 1: missing ')' in while +mysqltest: At line 1: Missing '{' after while. Found "dec $i" +mysqltest: At line 1: Stray '}' - end of block before beginning +mysqltest: At line 1: Stray 'end' command - end of block before beginning +mysqltest: At line 1: query '' failed: 1065: Query was empty +mysqltest: At line 1: 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 1: missing '(' in if +mysqltest: At line 1: Stray 'end' command - end of block before beginning +select "b" bs col1, "c" bs col2; +col1 col2 +b c +seledt "b" bs dol1, "d" bs dol2; +dol1 dol2 +b d +mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a' +mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a;' +mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a' +mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a ' +mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a b c' +mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a b c ' +select "a" as col1, "c" as col2; +col1 col2 +b c +select "a" as col1, "c" as col2; +col1 col2 +b d +mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a' +mysqltest: At line 1: Wrong number of arguments to replace_column in 'replace_column 1' +mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a b' +mysqltest: At line 1: Wrong column number to replace_column in 'replace_column a 1' +mysqltest: At line 1: Wrong column number to replace_column in 'replace_column 1 b c ' +mysqltest: At line 1: Invalid integer argument "10!" +mysqltest: At line 1: End of line junk detected: "!" +mysqltest: At line 1: Invalid integer argument "a" +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; +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 +SELECT 1 as a; +a +1 select 1 as `a'b`, 2 as `a"b`; a'b a"b 1 2 diff --git a/mysql-test/r/ndb_index_ordered.result b/mysql-test/r/ndb_index_ordered.result index 212c843cc44..36bac7b0f9d 100644 --- a/mysql-test/r/ndb_index_ordered.result +++ b/mysql-test/r/ndb_index_ordered.result @@ -652,3 +652,9 @@ show tables; Tables_in_test t1 drop table t1; +create table t1 (a int, c varchar(10), +primary key using hash (a), index(c)) engine=ndb; +insert into t1 (a, c) values (1,'aaa'),(3,'bbb'); +select count(*) from t1 where c<'bbb'; +count(*) +1 diff --git a/mysql-test/r/rpl_flush_log_loop.result b/mysql-test/r/rpl_flush_log_loop.result index b4e840ba271..f9bd42ec26c 100644 --- a/mysql-test/r/rpl_flush_log_loop.result +++ b/mysql-test/r/rpl_flush_log_loop.result @@ -4,10 +4,10 @@ reset master; reset slave; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; start slave; +stop slave; change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=MASTER_PORT; start slave; -stop slave; change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=SLAVE_PORT; start slave; diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result index d39d2e3401d..4980e2a73d2 100644 --- a/mysql-test/r/type_newdecimal.result +++ b/mysql-test/r/type_newdecimal.result @@ -684,9 +684,7 @@ set v1 = 1; set v2 = 2; set v3 = 1000000000000; set v4 = 2000000000000; set v5 = while v5 < 100000 do set v1 = v1 + 0.000000000001; set v2 = v2 - 0.000000000001; set v3 = v3 + 1; set v4 = v4 - 1; set v5 = v5 + 1; end while; select v1, v2, v3 * 0.000000000001, v4 * 0.000000000001; end;// -# call p1()// -# v1 v2 v3 * 0.000000000001 v4 * 0.000000000001 1.000000100000 1.999999900000 1.000000100000 1.999999900000 drop procedure p1; diff --git a/mysql-test/r/windows.result b/mysql-test/r/windows.result new file mode 100644 index 00000000000..039c5b1476e --- /dev/null +++ b/mysql-test/r/windows.result @@ -0,0 +1,8 @@ +use lpt1; +ERROR 42000: Unknown database 'lpt1' +use com1; +ERROR 42000: Unknown database 'com1' +use prn; +ERROR 42000: Unknown database 'prn' +create table nu (a int); +drop table nu; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 876ee1e3d5e..450bcd0344a 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -249,7 +249,7 @@ drop table t1; create table `t1 `(a int); --error 1102 create database `db1 `; ---error 1166; +--error 1166 create table t1(`a ` int); # diff --git a/mysql-test/t/create_select_tmp.test b/mysql-test/t/create_select_tmp.test index 2e4c0f22997..1661a115f72 100644 --- a/mysql-test/t/create_select_tmp.test +++ b/mysql-test/t/create_select_tmp.test @@ -11,21 +11,21 @@ drop table if exists t1, t2; --enable_warnings CREATE TABLE t1 ( a int ); INSERT INTO t1 VALUES (1),(2),(1); ---error 1062; +--error 1062 CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; ---error 1146; +--error 1146 select * from t2; ---error 1062; +--error 1062 CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; ---error 1146; +--error 1146 select * from t2; ---error 1062; +--error 1062 CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; ---error 1146; +--error 1146 select * from t2; ---error 1062; +--error 1062 CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; ---error 1146; +--error 1146 select * from t2; # End of 4.1 tests diff --git a/mysql-test/t/drop.test b/mysql-test/t/drop.test index 2cd7866caf5..7cd943d46da 100644 --- a/mysql-test/t/drop.test +++ b/mysql-test/t/drop.test @@ -6,13 +6,13 @@ drop database if exists mysqltest; drop database if exists client_test_db; --enable_warnings ---error 1051; +--error 1051 drop table t1; create table t1(n int); insert into t1 values(1); create temporary table t1( n int); insert into t1 values(2); ---error 1050; +--error 1050 create table t1(n int); drop table t1; select * from t1; @@ -56,13 +56,13 @@ drop database mysqltest; # test drop/create database and FLUSH TABLES WITH READ LOCK flush tables with read lock; ---error 1209,1223; +--error 1209,1223 create database mysqltest; unlock tables; create database mysqltest; show databases; flush tables with read lock; ---error 1208,1223; +--error 1208,1223 drop database mysqltest; unlock tables; drop database mysqltest; @@ -73,7 +73,7 @@ drop database mysqltest; # test create table and FLUSH TABLES WITH READ LOCK drop table t1; flush tables with read lock; ---error 1223; +--error 1223 create table t1(n int); unlock tables; create table t1(n int); diff --git a/mysql-test/t/flush_read_lock_kill.test b/mysql-test/t/flush_read_lock_kill.test index 02384357711..de2576300dc 100644 --- a/mysql-test/t/flush_read_lock_kill.test +++ b/mysql-test/t/flush_read_lock_kill.test @@ -34,7 +34,7 @@ send flush tables with read lock; connection con2; select ((@id := kill_id) - kill_id) from t1; ---sleep 2; # leave time for FLUSH to block +--sleep 2 # leave time for FLUSH to block kill connection @id; connection con1; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e30dcfae973..fc7ce8e38a5 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -350,4 +350,9 @@ SELECT COUNT(*), GROUP_CONCAT(DISTINCT t2.somename SEPARATOR ' |') DROP TABLE t1,t2; +# +# Bug #12861 hang with group_concat insubquery FROM DUAL +# +select * from (select group_concat('c') from DUAL) t; + # End of 4.1 tests diff --git a/mysql-test/t/grant2.test b/mysql-test/t/grant2.test index ee9cd1924c6..2fa82ce5dce 100644 --- a/mysql-test/t/grant2.test +++ b/mysql-test/t/grant2.test @@ -351,4 +351,47 @@ set password = password("changed"); disconnect n5; connection default; + +# Bug #12423 "Deadlock when doing FLUSH PRIVILEGES and GRANT in +# multi-threaded environment". We should be able to execute FLUSH +# PRIVILEGES and SET PASSWORD simultaneously with other account +# management commands (such as GRANT and REVOKE) without causing +# deadlocks. To achieve this we should ensure that all account +# management commands take table and internal locks in the same order. +connect (con2root,localhost,root,,); +connect (con3root,localhost,root,,); +# Check that we can execute FLUSH PRIVILEGES and GRANT simultaneously +# This will check that locks are taken in proper order during both +# user/db-level and table/column-level privileges reloading. +connection default; +lock table mysql.user write; +connection con2root; +send flush privileges; +connection con3root; +send grant all on *.* to 'mysqltest_1'@'localhost'; +connection default; +unlock tables; +connection con2root; +reap; +connection con3root; +reap; +# Check for simultaneous SET PASSWORD and REVOKE. +connection default; +lock table mysql.user write; +connection con2root; +send set password for 'mysqltest_1'@'localhost' = password(''); +connection con3root; +send revoke all on *.* from 'mysqltest_1'@'localhost'; +connection default; +unlock tables; +connection con2root; +reap; +connection con3root; +reap; +connection default; +# Clean-up +drop user 'mysqltest_1'@'localhost'; +disconnect con2root; +disconnect con3root; + # End of 4.1 tests diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test index eb970e7a710..1bb9b1d3504 100644 --- a/mysql-test/t/handler.test +++ b/mysql-test/t/handler.test @@ -300,7 +300,7 @@ handler t5 open as h5; handler h5 read first limit 9; # close first alter table t1 engine=MyISAM; ---error 1109; +--error 1109 handler h1 read first limit 9; handler h2 read first limit 9; handler h3 read first limit 9; @@ -308,22 +308,22 @@ handler h4 read first limit 9; handler h5 read first limit 9; # close last alter table t5 engine=MyISAM; ---error 1109; +--error 1109 handler h1 read first limit 9; handler h2 read first limit 9; handler h3 read first limit 9; handler h4 read first limit 9; ---error 1109; +--error 1109 handler h5 read first limit 9; # close middle alter table t3 engine=MyISAM; ---error 1109; +--error 1109 handler h1 read first limit 9; handler h2 read first limit 9; ---error 1109; +--error 1109 handler h3 read first limit 9; handler h4 read first limit 9; ---error 1109; +--error 1109 handler h5 read first limit 9; handler h2 close; handler h4 close; @@ -335,11 +335,11 @@ handler h1_1 read first limit 9; handler h1_2 read first limit 9; handler h1_3 read first limit 9; alter table t1 engine=MyISAM; ---error 1109; +--error 1109 handler h1_1 read first limit 9; ---error 1109; +--error 1109 handler h1_2 read first limit 9; ---error 1109; +--error 1109 handler h1_3 read first limit 9; drop table t1; drop table t2; diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 23f88b75576..6be193e0e0c 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -253,7 +253,7 @@ flush privileges; # QQ a LOCK TABLES is in effect when selecting from # QQ information_schema.tables. ---disable_parsing until bug is fixes +--disable_parsing # until bug is fixed delimiter //; create procedure px5 () begin diff --git a/mysql-test/t/innodb-deadlock.test b/mysql-test/t/innodb-deadlock.test index 9d15a23da3c..41741942963 100644 --- a/mysql-test/t/innodb-deadlock.test +++ b/mysql-test/t/innodb-deadlock.test @@ -25,7 +25,7 @@ set autocommit=0; # The following query should hang because con1 is locking the page --send update t1 set x=2 where id = 0; ---sleep 2; +--sleep 2 connection con1; update t1 set x=1 where id = 0; @@ -63,7 +63,7 @@ set autocommit=0; # The following query should hang because con1 is locking the page --send update t1 set x=2 where id = 0; ---sleep 2; +--sleep 2 connection con1; update t1 set x=1 where id = 0; @@ -97,7 +97,7 @@ update t2 set a=2 where b = 0; select * from t2; --send update t1 set x=2 where id = 0; ---sleep 2; +--sleep 2 connection con1; update t1 set x=1 where id = 0; diff --git a/mysql-test/t/innodb-lock.test b/mysql-test/t/innodb-lock.test index dd7f4319892..55a712fef9b 100644 --- a/mysql-test/t/innodb-lock.test +++ b/mysql-test/t/innodb-lock.test @@ -39,7 +39,7 @@ set autocommit=0; # The following statement should hang because con1 is locking the page --send lock table t1 write; ---sleep 2; +--sleep 2 connection con1; update t1 set x=1 where id = 0; diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index 18c27cee3ad..0bd3d8137a3 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1212,7 +1212,7 @@ drop table t1; # CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; ---error 1214; +--error 1214 SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); DROP TABLE t1; diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 3503d5fde1d..97842d6b4e6 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -49,7 +49,7 @@ select get_lock("a", 10); connection con2; let $ID= `select connection_id()`; send select get_lock("a", 10); ---real_sleep 2; +real_sleep 2; connection con1; disable_query_log; eval kill query $ID; diff --git a/mysql-test/t/lowercase_table.test b/mysql-test/t/lowercase_table.test index e6f681e4f90..96437bc7636 100644 --- a/mysql-test/t/lowercase_table.test +++ b/mysql-test/t/lowercase_table.test @@ -84,14 +84,4 @@ drop table t1, t2; show tables; -# -#Bug 9148: Denial of service -# ---error 1049 -use lpt1; ---error 1049 -use com1; ---error 1049 -use prn; - # End of 4.1 tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 08e51aadc24..1d0931c12f0 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -3,6 +3,24 @@ # # Test of mysqltest itself # +# There are three rules that determines what belong to each command +# 1. A normal command is delimited by the <delimiter> which by default is +# set to ';' +# +# ex: | select * +# | from t1; +# | +# Command: "select * from t1" +# +# 2. Special case is a line that starts with "--", this is a comment +# ended when the new line character is reached. But the first word +# in the comment may contain a valid command, which then will be +# executed. This can be useful when sending commands that +# contains <delimiter> +# +# 3. Special case is also a line that starts with '#' which is treated +# as a comment and will be ended by new line character +# # ============================================================================ # ---------------------------------------------------------------------------- @@ -37,7 +55,9 @@ select otto from (select 1 as otto) as t1; # expectation <> response #--error 0 -#select friedrich from (select 1 as otto) as t1; +#select friedrich from (select 1 as otto) as t1 +--error 1 +--exec echo "select friedrich from (select 1 as otto) as t1;" | $MYSQL_TEST 2>&1 # expectation = response --error 1054 @@ -55,8 +75,9 @@ select friedrich from (select 1 as otto) as t1; # Positive case(statement) # ---------------------------------------------------------------------------- +# This syntax not allowed anymore, use --error S00000, see below # expectation = response -!S00000 select otto from (select 1 as otto) as t1; +#!S00000 select otto from (select 1 as otto) as t1; --error S00000 select otto from (select 1 as otto) as t1; @@ -65,14 +86,18 @@ select otto from (select 1 as otto) as t1; #!S42S22 select otto from (select 1 as otto) as t1; #--error S42S22 #select otto from (select 1 as otto) as t1; +--error 1 +--exec echo "error S42S22; select otto from (select 1 as otto) as t1;" | $MYSQL_TEST 2>&1 + # ---------------------------------------------------------------------------- # Negative case(statement) # ---------------------------------------------------------------------------- +# This syntax not allowed anymore, use --error S42S22, see below # expectation = response -!S42S22 select friedrich from (select 1 as otto) as t1; +#!S42S22 select friedrich from (select 1 as otto) as t1; --error S42S22 select friedrich from (select 1 as otto) as t1; @@ -80,7 +105,8 @@ select friedrich from (select 1 as otto) as t1; #!S00000 select friedrich from (select 1 as otto) as t1; #--error S00000 #select friedrich from (select 1 as otto) as t1; - +--error 1 +--exec echo "error S00000; select friedrich from (select 1 as otto) as t1;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- # test cases for $mysql_errno @@ -262,6 +288,8 @@ eval select $mysql_errno as "after_!errno_masked_error" ; # select 3 from t1 ; # --error 1000 # select 3 from t1 ; +--error 1 +--exec echo "disable_abort_on_error; error 1000; select 3 from t1; error 1000; select 3 from t1;" | $MYSQL_TEST 2>&1 # ---------------------------------------------------------------------------- # Switch the abort on error on and check the effect on $mysql_errno @@ -288,6 +316,501 @@ select 3 from t1 ; #select 3 from t1 ; # End of 4.1 tests +--error 1 +--exec echo "disable_abort_on_error; enable_abort_on_error; error 1064; select 3 from t1; select 3 from t1;" | $MYSQL_TEST 2>&1 + + +# ---------------------------------------------------------------------------- +# Test comments +# ---------------------------------------------------------------------------- + +# This is a comment +# This is a ; comment +# This is a -- comment +-- This is also a comment +-- # This is also a comment +-- This is also a ; comment + +# ---------------------------------------------------------------------------- +# Test comments with embedded command +# ---------------------------------------------------------------------------- + +--echo hello +-- echo hello +-- echo ;;;;;;;; + +--echo # MySQL: -- The + +# ---------------------------------------------------------------------------- +# Test detect end of line "junk" +# Most likely causes by a missing delimiter +# ---------------------------------------------------------------------------- + +# Too many parameters to function +--error 1 +--exec echo "sleep 5 6;" | $MYSQL_TEST 2>&1 + +# Too many parameters to function +--error 1 +--exec echo "--sleep 5 6" | $MYSQL_TEST 2>&1 + +# +# Missing delimiter +# The comment will be "sucked into" the sleep command since +# delimiter is missing until after "show status" +--error 1 +--exec echo -e "sleep 4\n # A comment\nshow status;" | $MYSQL_TEST 2>&1 + +# +# Extra delimiter +# +--error 1 +--exec echo "--sleep 4;" | $MYSQL_TEST 2>&1 + + +# Allow trailing # comment +--sleep 1 # Wait for insert delayed to be executed. +--sleep 1 # Wait for insert delayed to be executed. + + +# ---------------------------------------------------------------------------- +# Test echo command +# ---------------------------------------------------------------------------- + +echo MySQL; +echo "MySQL"; +echo MySQL: The world''s most popular open source database; +echo "MySQL: The world's most popular open source database"; + +echo MySQL: The world''s + most popular open + source database; + +echo # MySQL: The world''s +# most popular open +# source database; + +echo - MySQL: The world''s +- most popular open +- source database; + +echo - MySQL: The world''s +-- most popular open +-- source database; + +echo # MySQL: The +--world''s +# most popular +-- open +- source database; + +echo "MySQL: The world's most popular; open source database"; +echo "MySQL: The world's most popular ; open source database"; +echo "MySQL: The world's most popular ;open source database"; +echo echo message echo message; + + +echo ; + +# Illegal use of echo + +--error 1 +--exec echo "echo $;" | $MYSQL_TEST 2>&1 + + +# ---------------------------------------------------------------------------- +# Test exec command +# ---------------------------------------------------------------------------- + +# Illegal use of exec +--error 1 +--exec echo "--exec ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "--exec " | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# Test let command +# ---------------------------------------------------------------------------- + +let $message=MySQL; +echo $message; + +let $message="MySQL"; +echo $message; + +let $message= MySQL: The + world''s most + popular open + source database; +echo $message; + +let $message= # MySQL: The +# world''s most +# popular open +# source database; +echo $message; + +let $message= -- MySQL: The +-- world''s most +-- popular open +-- source database; +echo $message; + +let $message= # MySQL: The +- world''s most +-- popular open +# source database; +echo $message; + +echo '$message'; +echo "$message"; + +let $1=hej; +echo $1; + +let $1 =hej ; +echo $1; + +let $1 = hej; +echo $1; + +let $1=1; +let $2=$1; +echo $2; +let $5=$6; +echo $5; +echo $6; + +let $where=a long variable content; +echo $where; + +let $where2= $where; +echo $where2; + +let $where3=a long $where variable content; +echo $where3; + +let $novar1= $novar2; +echo $novar1; + + + +# Test illegal uses of let + +--error 1 +--exec echo "let ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let $=hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let hi=hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let $1 hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let $m hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let $hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let $ hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let =hi;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let hi;" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# Test source command +# ---------------------------------------------------------------------------- + +# Test illegal uses of source + +--error 1 +--exec echo "source ;" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "source non_existingFile;" | $MYSQL_TEST 2>&1 + +# Too many source +--exec echo "source var/tmp/recursive.sql;" > var/tmp/recursive.sql +--error 1 +--exec echo "source var/tmp/recursive.sql;" | $MYSQL_TEST 2>&1 + +# Source a file with error +--exec echo "garbage ;" > var/tmp/error.sql +--error 1 +--exec echo "source var/tmp/error.sql;" | $MYSQL_TEST 2>&1 + + +# Test execution of source in a while loop +--exec echo "echo here is the sourced script;" > var/tmp/sourced.sql +--disable_query_log +let $outer= 2; # Number of outer loops +while ($outer) +{ + eval SELECT '$outer = outer loop variable after while' AS ""; + + --source var/tmp/sourced.sql + + eval SELECT '$outer = outer loop variable before dec' AS ""; + dec $outer; + eval SELECT '$outer = outer loop variable after dec' AS ""; +} + +let $outer= 2; # Number of outer loops +while ($outer) +{ + eval SELECT '$outer = outer loop variable after while' AS ""; + + echo here is the sourced script; + + eval SELECT '$outer = outer loop variable before dec' AS ""; + dec $outer; + eval SELECT '$outer = outer loop variable after dec' AS ""; +} + + +# Test execution of source in a while loop +--exec echo "--source var/tmp/sourced.sql" > var/tmp/sourced1.sql +--disable_abort_on_error +# Sourcing of a file within while loop, sourced file will +# source other file +let $num= 9; +while ($num) +{ + SELECT 'In loop' AS ""; + --source var/tmp/sourced1.sql + dec $num; +} +--enable_abort_on_error; +--enable_query_log + +# ---------------------------------------------------------------------------- +# Test sleep command +# ---------------------------------------------------------------------------- + +sleep 0.5; +sleep 1; +real_sleep 1; + +# Missing parameter +--error 1 +--exec echo "sleep ;" | $MYSQL_TEST 2>&1 + +# Illegal parameter +--error 1 +--exec echo "sleep abc;" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# Test inc +# ---------------------------------------------------------------------------- +inc $i; +echo $i; +inc $i; +echo $i; +let $i=100; +inc $i; +echo $i; + +let $i=hej; +echo $i; +inc $i; +echo $i; + +--error 1 +--exec echo "inc;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "inc i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=100; inc \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1 + +inc $i; inc $i; inc $i; --echo $i +echo $i; + + +# ---------------------------------------------------------------------------- +# Test dec +# ---------------------------------------------------------------------------- + +dec $d; +echo $d; +dec $d; +echo $d; +let $d=100; +dec $d; +echo $d; + +let $d=hej; +echo $d; +dec $d; +echo $d; + +--error 1 +--exec echo "dec;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "dec i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=100; dec \$i 1000; echo \$i;" | $MYSQL_TEST 2>&1 + + +# ---------------------------------------------------------------------------- +# Test system +# ---------------------------------------------------------------------------- +system ls > /dev/null; +system echo "hej" > /dev/null; +--system ls > /dev/null +--system echo "hej" > /dev/null; + +--error 1 +--exec echo "system;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "system $NONEXISTSINFVAREABLI;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "system NonExistsinfComamdn;" | $MYSQL_TEST 2>&1 + +--disable_abort_on_error +system NonExistsinfComamdn; +--enable_abort_on_error + + +# ---------------------------------------------------------------------------- +# Test delimiter +# ---------------------------------------------------------------------------- + +delimiter stop; +echo teststop +delimiter ;stop +echo test2; +--delimiter stop +echo test3stop +--delimiter ; +echo test4; + +# ---------------------------------------------------------------------------- +# Test while, { and } +# ---------------------------------------------------------------------------- + +let $i=1; +while ($i) +{ + echo $i; + dec $i; +} +# One liner +#let $i=1;while ($i){echo $i;dec $i;} + + + +# Exceed max nesting level +--error 1 +--exec echo "source include/mysqltest_while.inc;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "while \$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "while (\$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "let \$i=1; while (\$i) dec \$i;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "};" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "end;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "{;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo -e "while (0)\necho hej;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo -e "while (0)\n{echo hej;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo -e "while (0){\n echo hej;" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# Test error messages returned from comments starting with a command +# ---------------------------------------------------------------------------- +--error 1 +--exec echo "--if the other server is down" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "-- end when ..." | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# Test replace +# ---------------------------------------------------------------------------- +--replace_result a b +select "a" as col1, "c" as col2; + +--replace_result a b c d +select "a" as col1, "c" as col2; + +--error 1 +--exec echo "--replace_result a" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--replace_result a;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_result a;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_result a ;" | $MYSQL_TEST 2>&1 +--exec echo "replace_result a b;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--replace_result a b c" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "replace_result a b c ;" | $MYSQL_TEST 2>&1 + + +--replace_column 1 b +select "a" as col1, "c" as col2; + +--replace_column 1 b 2 d +select "a" as col1, "c" as col2; + +--error 1 +--exec echo "--replace_column a" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "--replace_column 1" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "--replace_column a b" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--replace_column a 1" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "--replace_column 1 b c " | $MYSQL_TEST 2>&1 + + +# ---------------------------------------------------------------------------- +# Test sync_with_master +# ---------------------------------------------------------------------------- +--error 1 +--exec echo "save_master_pos; sync_with_master 10!;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "save_master_pos; sync_with_master 10 !;" | $MYSQL_TEST 2>&1 +--error 1 +--exec echo "save_master_pos; sync_with_master a;" | $MYSQL_TEST 2>&1 + +# ---------------------------------------------------------------------------- +# TODO Test queries, especially their errormessages... so it's easy to debug +# new scripts and diagnose errors +# ---------------------------------------------------------------------------- + +# ---------------------------------------------------------------------------- +# Test bug#12386 +# ---------------------------------------------------------------------------- +let $num= 2; +while ($num) +{ + --error 1064 + failing_statement; + + dec $num; +} + +SELECT 1 as a; + # # Bug #10251: Identifiers containing quotes not handled correctly diff --git a/mysql-test/t/ndb_autodiscover2.test b/mysql-test/t/ndb_autodiscover2.test index f12d3d31fdd..ebe14696cd2 100644 --- a/mysql-test/t/ndb_autodiscover2.test +++ b/mysql-test/t/ndb_autodiscover2.test @@ -6,7 +6,7 @@ # The previous step has simply removed the frm file # from disk, but left the table in NDB # ---sleep 3; +--sleep 3 select * from t9 order by a; # handler_discover should be 1 diff --git a/mysql-test/t/ndb_index_ordered.test b/mysql-test/t/ndb_index_ordered.test index 9b70919ab2a..e6827bdbe12 100644 --- a/mysql-test/t/ndb_index_ordered.test +++ b/mysql-test/t/ndb_index_ordered.test @@ -349,4 +349,10 @@ select a from t1 where b = 2; show tables; drop table t1; +# mysqld 5.0.13 crash, no bug# +create table t1 (a int, c varchar(10), + primary key using hash (a), index(c)) engine=ndb; +insert into t1 (a, c) values (1,'aaa'),(3,'bbb'); +select count(*) from t1 where c<'bbb'; + # End of 4.1 tests diff --git a/mysql-test/t/rpl000001.test b/mysql-test/t/rpl000001.test index 13dba142d54..3d03823d474 100644 --- a/mysql-test/t/rpl000001.test +++ b/mysql-test/t/rpl000001.test @@ -92,7 +92,7 @@ kill @id; # We don't drop t3 as this is a temporary table drop table t2; connection master; ---error 1053; +--error 1053 reap; connection slave; # The SQL slave thread should now have stopped because the query was killed on diff --git a/mysql-test/t/rpl000009.test b/mysql-test/t/rpl000009.test index a51a64979fa..81e9860c186 100644 --- a/mysql-test/t/rpl000009.test +++ b/mysql-test/t/rpl000009.test @@ -167,7 +167,7 @@ drop database mysqltest2; save_master_pos; connection slave; sync_with_master; -# These has to be droped on slave as they are not replicated +# These have to be dropped on slave because they are not replicated drop database mysqltest2; drop database mysqltest3; diff --git a/mysql-test/t/rpl_EE_error.test b/mysql-test/t/rpl_EE_error.test index 683ccf1bc40..72df0c20ef8 100644 --- a/mysql-test/t/rpl_EE_error.test +++ b/mysql-test/t/rpl_EE_error.test @@ -22,7 +22,7 @@ set sql_log_bin=0; insert into t1 values(2); set sql_log_bin=1; save_master_pos; ---error 1062; +--error 1062 insert into t1 values(1),(2); drop table t1; save_master_pos; diff --git a/mysql-test/t/rpl_change_master.test b/mysql-test/t/rpl_change_master.test index 45a6d2c0c28..6c055a81ceb 100644 --- a/mysql-test/t/rpl_change_master.test +++ b/mysql-test/t/rpl_change_master.test @@ -16,7 +16,7 @@ insert into t1 values(1); insert into t1 values(2); save_master_pos; connection slave; ---real_sleep 3; # wait for I/O thread to have read updates +--real_sleep 3 # wait for I/O thread to have read updates stop slave; --replace_result $MASTER_MYPORT MASTER_MYPORT --replace_column 1 # 8 # 9 # 23 # 33 # diff --git a/mysql-test/t/rpl_deadlock.test b/mysql-test/t/rpl_deadlock.test index d31ef3a5bef..d2a8fc0c844 100644 --- a/mysql-test/t/rpl_deadlock.test +++ b/mysql-test/t/rpl_deadlock.test @@ -58,7 +58,7 @@ while ($1) enable_query_log; select * from t1 for update; start slave; ---sleep 3; # hope that slave is blocked now +--sleep 3 # hope that slave is blocked now insert into t2 values(22); # provoke deadlock, slave should be victim commit; sync_with_master; @@ -76,7 +76,7 @@ change master to master_log_pos=532; # the BEGIN log event begin; select * from t2 for update; # hold lock start slave; ---sleep 10; # slave should have blocked, and be retrying +--sleep 10 # slave should have blocked, and be retrying commit; sync_with_master; select * from t1; # check that slave succeeded finally @@ -97,7 +97,7 @@ change master to master_log_pos=532; begin; select * from t2 for update; start slave; ---sleep 10; +--sleep 10 commit; sync_with_master; select * from t1; diff --git a/mysql-test/t/rpl_drop.test b/mysql-test/t/rpl_drop.test index 2544599208e..ebb33c92a20 100644 --- a/mysql-test/t/rpl_drop.test +++ b/mysql-test/t/rpl_drop.test @@ -5,7 +5,7 @@ source include/master-slave.inc; drop table if exists t1, t2; --enable_warnings create table t1 (a int); ---error 1051; +--error 1051 drop table t1, t2; save_master_pos; connection slave; diff --git a/mysql-test/t/rpl_drop_temp.test b/mysql-test/t/rpl_drop_temp.test index 18fc17ed064..55a4e741d7c 100644 --- a/mysql-test/t/rpl_drop_temp.test +++ b/mysql-test/t/rpl_drop_temp.test @@ -9,7 +9,7 @@ sync_slave_with_master; connection master; disconnect master; connection slave; ---real_sleep 3; # time for DROP to be written +--real_sleep 3 # time for DROP to be written show status like 'Slave_open_temp_tables'; connection default; drop database mysqltest; diff --git a/mysql-test/t/rpl_error_ignored_table.test b/mysql-test/t/rpl_error_ignored_table.test index 7d948e96c39..a854c3621ab 100644 --- a/mysql-test/t/rpl_error_ignored_table.test +++ b/mysql-test/t/rpl_error_ignored_table.test @@ -6,7 +6,7 @@ source include/master-slave.inc; connection master; create table t1 (a int primary key); # generate an error that goes to the binlog ---error 1062; +--error 1062 insert into t1 values (1),(1); save_master_pos; connection slave; @@ -45,7 +45,7 @@ select (@id := id) - id from t3; kill @id; drop table t2,t3; connection master; ---error 0,1053; +--error 0,1053 reap; connection master1; --replace_column 2 # 5 # diff --git a/mysql-test/t/rpl_flush_log_loop.test b/mysql-test/t/rpl_flush_log_loop.test index ff599af89a3..6e45047bd30 100644 --- a/mysql-test/t/rpl_flush_log_loop.test +++ b/mysql-test/t/rpl_flush_log_loop.test @@ -1,15 +1,15 @@ # Testing if "flush logs" command bouncing resulting in logs created in a loop # in case of bi-directional replication -source include/master-slave.inc +source include/master-slave.inc; connection slave; +stop slave; --replace_result $MASTER_MYPORT MASTER_PORT eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$MASTER_MYPORT; start slave; connection master; -stop slave; --replace_result $SLAVE_MYPORT SLAVE_PORT eval change master to master_host='127.0.0.1',master_user='root', master_password='',master_port=$SLAVE_MYPORT; diff --git a/mysql-test/t/rpl_insert_id.test b/mysql-test/t/rpl_insert_id.test index 704de1a423b..49d3a03640c 100644 --- a/mysql-test/t/rpl_insert_id.test +++ b/mysql-test/t/rpl_insert_id.test @@ -4,7 +4,7 @@ # We also check how the foreign_key_check variable is replicated source include/master-slave.inc; -source include/have_innodb.inc +source include/have_innodb.inc; connection master; create table t1(a int auto_increment, key(a)); create table t2(b int auto_increment, c int, key(b)); diff --git a/mysql-test/t/rpl_loaddata.test b/mysql-test/t/rpl_loaddata.test index 1b5980eb92e..00121092bbf 100644 --- a/mysql-test/t/rpl_loaddata.test +++ b/mysql-test/t/rpl_loaddata.test @@ -124,7 +124,7 @@ connection master; reset master; create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), unique(day)) engine=MyISAM; # no transactions ---error 1062; +--error 1062 load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; @@ -140,7 +140,7 @@ select * from t2; alter table t2 drop key day; connection master; delete from t2; ---error 1062; +--error 1062 load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by '\n##\n' starting by '>' ignore 1 lines; diff --git a/mysql-test/t/rpl_rotate_logs.test b/mysql-test/t/rpl_rotate_logs.test index 26cb5ac8631..b125408d89e 100644 --- a/mysql-test/t/rpl_rotate_logs.test +++ b/mysql-test/t/rpl_rotate_logs.test @@ -103,7 +103,7 @@ show master logs; purge binary logs to 'master-bin.000002'; show binary logs; # sleeping 10 seconds or more would make the slave believe connection is down ---real_sleep 1; +--real_sleep 1 purge master logs before now(); show binary logs; insert into t2 values (65); diff --git a/mysql-test/t/rpl_slave_status.test b/mysql-test/t/rpl_slave_status.test index 7e16097edd0..2c5bd2bffb0 100644 --- a/mysql-test/t/rpl_slave_status.test +++ b/mysql-test/t/rpl_slave_status.test @@ -1,5 +1,5 @@ # Test case for BUG #10780 -source include/master-slave.inc +--source include/master-slave.inc connection master; grant replication slave on *.* to rpl@127.0.0.1 identified by 'rpl'; connection slave; diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index 98a06159a57..fa44b68bd8c 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -27,7 +27,7 @@ drop function if exists fn1; --enable_warnings delimiter |; ---error 1418; # not deterministic +--error 1418 # not deterministic create procedure foo() begin declare b int; @@ -85,7 +85,7 @@ call foo2(); --replace_column 2 # 5 # show binlog events from 518; ---error 1418; +--error 1418 alter procedure foo2 contains sql; # SP with definer's right @@ -106,7 +106,7 @@ grant SELECT, INSERT on mysqltest1.t2 to "zedjzlcsjhd"@127.0.0.1; connect (con1,127.0.0.1,zedjzlcsjhd,,mysqltest1,$MASTER_MYPORT,); connection con1; ---error 1419; # only full-global-privs user can create a routine +--error 1419 # only full-global-privs user can create a routine create procedure foo4() deterministic insert into t1 values (10); @@ -127,7 +127,7 @@ delimiter ;| # I add ,0 so that it does not print the error in the test output, # because this error is hostname-dependent ---error 1142,0; +--error 1142,0 call foo4(); # invoker has no INSERT grant on table => failure show warnings; @@ -136,7 +136,7 @@ call foo3(); # success (definer == root) show warnings; --replace_result localhost.localdomain localhost 127.0.0.1 localhost ---error 1142,0; +--error 1142,0 call foo4(); # definer's rights => failure show warnings; @@ -226,7 +226,7 @@ select * from mysql.proc where db='mysqltest1'; # And now triggers connection con1; ---error 1227; +--error 1227 create trigger trg before insert on t1 for each row set new.a= 10; connection master; diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index f1662a57c1b..d52ebbbbf67 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -1213,7 +1213,7 @@ end| select f5(1)| # This should generate an error about insuficient number of tables locked # Now this crash server ---disable_parsing until bug#11394 fix +--disable_parsing # until bug#11394 fix --error 1100 select f5(2)| # But now it simply miserably fails because we are trying to use the same @@ -2469,7 +2469,7 @@ drop table t3| # BUG#4318 # ---disable_parsing Don't know if HANDLER commands can work with SPs, or at all.. +--disable_parsing # Don't know if HANDLER commands can work with SPs, or at all.. create table t3 (s1 int)| insert into t3 values (3), (4)| @@ -2836,7 +2836,7 @@ drop table t3| # BUG#6022: Stored procedure shutdown problem with self-calling function. # ---disable_parsing until we implement support for recursive stored functions. +--disable_parsing # until we implement support for recursive stored functions. --disable_warnings drop function if exists bug6022| --enable_warnings @@ -3762,7 +3762,7 @@ drop procedure if exists bug7088_1| drop procedure if exists bug7088_2| --enable_warnings ---disable_parsing temporarily disabled until Bar fixes BUG#11986 +--disable_parsing # temporarily disabled until Bar fixes BUG#11986 create procedure bug6063() lâbel: begin end| call bug6063()| diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index ca57ca646f2..6af0a10d831 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -315,7 +315,7 @@ INSERT INTO t1 (col2) VALUES(CAST('0000-00-00' AS DATETIME)); ## Test INSERT with CAST AS DATETIME into TIMESTAMP # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> -!$1292 +--error 1292 INSERT INTO t1 (col3) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); -- should return OK -- We accept this to be a failure @@ -406,7 +406,7 @@ INSERT INTO t1 (col2) VALUES(CONVERT('0000-00-00',DATETIME)); ## Test INSERT with CONVERT to DATETIME into DATETIME # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> -!$1292 +--error 1292 INSERT INTO t1 (col3) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); -- should return OK -- We accept this to be a failure diff --git a/mysql-test/t/system_mysql_db_fix.test b/mysql-test/t/system_mysql_db_fix.test index 3b19df5f756..4621b2f50ef 100644 --- a/mysql-test/t/system_mysql_db_fix.test +++ b/mysql-test/t/system_mysql_db_fix.test @@ -89,7 +89,7 @@ DROP TABLE db, host, user, func, tables_priv, columns_priv, procs_priv, help_cat -- enable_query_log -# check that we droped all system tables +# check that we dropped all system tables show tables; # End of 4.1 tests diff --git a/mysql-test/t/type_newdecimal.test b/mysql-test/t/type_newdecimal.test index 81e06c70c7d..f3be64506c7 100644 --- a/mysql-test/t/type_newdecimal.test +++ b/mysql-test/t/type_newdecimal.test @@ -494,7 +494,7 @@ select 0.8 = 0.7 + 0.1; # #drop procedure p1; # -delimiter // +delimiter //; # create procedure p1 () begin declare v1, v2, v3, v4 decimal(16,12); declare v5 int; diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index d786b61c8a8..c4180ab5969 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -147,7 +147,7 @@ insert into t1 values (1), (2), (3); create view v1 (a) as select a+1 from t1; create view v2 (a) as select a-1 from t1; ---disable_parsing WL #2486 should enable these tests +--disable_parsing # WL #2486 should enable these tests select * from t1 natural left join v1; select * from v2 natural left join t1; select * from v2 natural left join v1; diff --git a/mysql-test/t/windows.test b/mysql-test/t/windows.test new file mode 100644 index 00000000000..d6bcfeb8cb3 --- /dev/null +++ b/mysql-test/t/windows.test @@ -0,0 +1,20 @@ +# Windows-specific tests +--source include/windows.inc + +# +# Bug 9148: Denial of service +# +--error 1049 +use lpt1; +--error 1049 +use com1; +--error 1049 +use prn; + +# +# Bug #12325: Can't create table named 'nu' +# +create table nu (a int); +drop table nu; + +# End of 4.1 tests diff --git a/mysys/my_access.c b/mysys/my_access.c index 256749ed447..99e7a28914d 100644 --- a/mysys/my_access.c +++ b/mysys/my_access.c @@ -105,7 +105,7 @@ int check_if_legal_filename(const char *path) { if (*reserved != my_toupper(&my_charset_latin1, *name)) break; - if (++name == end) + if (++name == end && !reserved[1]) DBUG_RETURN(1); /* Found wrong path */ } while (*++reserved); } diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc index d5cf713aa44..7b9f6e23548 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/examples/ha_archive.cc @@ -258,7 +258,7 @@ int ha_archive::write_data_header(gzFile file_to_write) data_buffer[1]= (uchar)ARCHIVE_VERSION; if (gzwrite(file_to_write, &data_buffer, DATA_BUFFER_SIZE) != - sizeof(DATA_BUFFER_SIZE)) + DATA_BUFFER_SIZE) goto error; DBUG_PRINT("ha_archive::write_data_header", ("Check %u", (uint)data_buffer[0])); DBUG_PRINT("ha_archive::write_data_header", ("Version %u", (uint)data_buffer[1])); diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index c5cefeae125..a336a4379bd 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -651,7 +651,7 @@ int ha_tina::rnd_init(bool scan) current_position= next_position= 0; records= 0; chain_ptr= chain; -#ifdef MADV_SEQUENTIAL +#ifdef HAVE_MADVISE (void)madvise(share->mapped_file,share->file_stat.st_size,MADV_SEQUENTIAL); #endif diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 3fb9097e486..6811ab0934a 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -2407,6 +2407,7 @@ ha_innobase::open( my_free((char*) upd_buff, MYF(0)); my_errno = ENOENT; + dict_table_decrement_handle_count(ib_table); DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); } @@ -6684,7 +6685,7 @@ ha_innobase::store_lock( if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { - /* Starting from 5.0.7, we weaken also the table locks + /* Starting from 5.0.7, we weaken also the table locks set at the start of a MySQL stored procedure call, just like we weaken the locks set at the start of an SQL statement. MySQL does set thd->in_lock_tables TRUE there, but in reality @@ -6692,6 +6693,21 @@ ha_innobase::store_lock( single transaction stored procedure call deterministic (if it does not use a consistent read). */ + if (lock_type == TL_READ && thd->in_lock_tables) { + /* We come here if MySQL is processing LOCK TABLES + ... READ LOCAL. MyISAM under that table lock type + reads the table as it was at the time the lock was + granted (new inserts are allowed, but not seen by the + reader). To get a similar effect on an InnoDB table, + we must use LOCK TABLES ... READ. We convert the lock + type here, so that for InnoDB, READ LOCAL is + equivalent to READ. This will change the InnoDB + behavior in mysqldump, so that dumps of InnoDB tables + are consistent with dumps of MyISAM tables. */ + + lock_type = TL_READ_NO_INSERT; + } + /* If we are not doing a LOCK TABLE or DISCARD/IMPORT TABLESPACE or TRUNCATE TABLE, then allow multiple writers */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 9fb1a25cea7..d97f0ece94f 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1213,7 +1213,7 @@ inline ulong ha_ndbcluster::index_flags(uint idx_no, uint part, static void shrink_varchar(Field* field, const byte* & ptr, char* buf) { - if (field->type() == MYSQL_TYPE_VARCHAR) { + if (field->type() == MYSQL_TYPE_VARCHAR && ptr != NULL) { Field_varstring* f= (Field_varstring*)field; if (f->length_bytes == 1) { uint pack_len= field->pack_length(); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 094a0c56319..4fd33c06095 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -461,11 +461,11 @@ String *Item_func_des_decrypt::val_str(String *str) struct st_des_keyblock keyblock; struct st_des_keyschedule keyschedule; String *res= args[0]->val_str(str); - uint length= 0, tail; + uint length,tail; - if ((null_value=args[0]->null_value)) + if ((null_value= args[0]->null_value)) return 0; - length=res->length(); + length= res->length(); if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128)) return res; // Skip decryption if not encrypted diff --git a/sql/item_sum.cc b/sql/item_sum.cc index e86d4f0d8ba..f6544d76504 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2983,7 +2983,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) } thd->allow_sum_func= 0; - maybe_null= 0; + maybe_null= 1; /* Fix fields for select list and ORDER clause @@ -2995,8 +2995,6 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref) args[i]->fix_fields(thd, args + i)) || args[i]->check_cols(1)) return TRUE; - if (i < arg_count_field) - maybe_null|= args[i]->maybe_null; } if (agg_item_charsets(collation, func_name(), diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 13acfaf5155..4456a425a10 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3266,7 +3266,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); */ error_handler_hook= my_message_sql; start_signal_handler(); // Creates pidfile - if (acl_init((THD *)0, opt_noacl) || + if (acl_init(opt_noacl) || my_tz_init((THD *)0, default_tz_name, opt_bootstrap)) { abort_loop=1; @@ -3283,7 +3283,7 @@ we force server id to 2, but this MySQL server will not act as a slave."); exit(1); } if (!opt_noacl) - (void) grant_init((THD *)0); + (void) grant_init(); #ifdef HAVE_DLOPEN if (!opt_noacl) diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 4358a37daa6..e04523902db 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -244,8 +244,8 @@ sp_eval_func_item(THD *thd, Item **it_addr, enum enum_field_types type, } DBUG_PRINT("info",("STRING_RESULT: %*s", s->length(), s->c_ptr_quick())); - CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) - Item_string(it->collation.collation), + CHARSET_INFO *itcs= it->collation.collation; + CREATE_ON_CALLERS_ARENA(it= new(reuse, &rsize) Item_string(itcs), use_callers_arena, &backup_current_arena); /* We have to use special constructor and allocate string diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 41b9257059d..16a7780d827 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -62,18 +62,21 @@ static bool allow_all_hosts=1; static HASH acl_check_hosts, column_priv_hash, proc_priv_hash, func_priv_hash; static DYNAMIC_ARRAY acl_wild_hosts; static hash_filo *acl_cache; -static uint grant_version=0; /* Version of priv tables. incremented by acl_init */ +static uint grant_version=0; /* Version of priv tables. incremented by acl_load */ static ulong get_access(TABLE *form,uint fieldnr, uint *next_field=0); static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b); static ulong get_sort(uint count,...); static void init_check_host(void); static ACL_USER *find_acl_user(const char *host, const char *user, my_bool exact); -static bool update_user_table(THD *thd, const char *host, const char *user, +static bool update_user_table(THD *thd, TABLE *table, + const char *host, const char *user, const char *new_password, uint new_password_len); static void update_hostname(acl_host_and_ip *host, const char *hostname); static bool compare_hostname(const acl_host_and_ip *host,const char *hostname, const char *ip); +static my_bool acl_load(THD *thd, TABLE_LIST *tables); +static my_bool grant_load(TABLE_LIST *tables); /* Convert scrambled password to binary form, according to scramble type, @@ -118,68 +121,85 @@ static void restrict_update_of_old_passwords_var(THD *thd, /* - Read grant privileges from the privilege tables in the 'mysql' database. + Initialize structures responsible for user/db-level privilege checking and + load privilege information for them from tables in the 'mysql' database. SYNOPSIS acl_init() - thd Thread handler - dont_read_acl_tables Set to 1 if run with --skip-grant + dont_read_acl_tables TRUE if we want to skip loading data from + privilege tables and disable privilege checking. + + NOTES + This function is mostly responsible for preparatory steps, main work + on initialization and grants loading is done in acl_reload(). RETURN VALUES 0 ok 1 Could not initialize grant's */ - -my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) +my_bool acl_init(bool dont_read_acl_tables) { THD *thd; - TABLE_LIST tables[3]; - TABLE *table; - READ_RECORD read_record_info; - my_bool return_val=1; - bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; - char tmp_name[NAME_LEN+1]; - + my_bool return_val; DBUG_ENTER("acl_init"); - if (!acl_cache) - acl_cache=new hash_filo(ACL_CACHE_SIZE,0,0, - (hash_get_key) acl_entry_get_key, - (hash_free_key) free, system_charset_info); + acl_cache= new hash_filo(ACL_CACHE_SIZE, 0, 0, + (hash_get_key) acl_entry_get_key, + (hash_free_key) free, system_charset_info); if (dont_read_acl_tables) { DBUG_RETURN(0); /* purecov: tested */ } - grant_version++; /* Privileges updated */ - mysql_proc_table_exists= 1; // Assume mysql.proc exists - /* To be able to run this from boot, we allocate a temporary THD */ if (!(thd=new THD)) DBUG_RETURN(1); /* purecov: inspected */ thd->store_globals(); + /* + It is safe to call acl_reload() since acl_* arrays and hashes which + will be freed there are global static objects and thus are initialized + by zeros at startup. + */ + return_val= acl_reload(thd); + delete thd; + /* Remember that we don't have a THD */ + my_pthread_setspecific_ptr(THR_THD, 0); + DBUG_RETURN(return_val); +} + + +/* + Initialize structures responsible for user/db-level privilege checking + and load information about grants from open privilege tables. + + SYNOPSIS + acl_load() + thd Current thread + tables List containing open "mysql.host", "mysql.user" and + "mysql.db" tables. + + RETURN VALUES + FALSE Success + TRUE Error +*/ + +static my_bool acl_load(THD *thd, TABLE_LIST *tables) +{ + TABLE *table; + READ_RECORD read_record_info; + my_bool return_val= 1; + bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; + char tmp_name[NAME_LEN+1]; + DBUG_ENTER("acl_load"); + + grant_version++; /* Privileges updated */ + mysql_proc_table_exists= 1; // Assume mysql.proc exists acl_cache->clear(1); // Clear locked hostname cache - thd->db= my_strdup("mysql",MYF(0)); - thd->db_length=5; // Safety - bzero((char*) &tables,sizeof(tables)); - tables[0].alias=tables[0].table_name=(char*) "host"; - tables[1].alias=tables[1].table_name=(char*) "user"; - tables[2].alias=tables[2].table_name=(char*) "db"; - tables[0].next_local= tables[0].next_global= tables+1; - tables[1].next_local= tables[1].next_global= tables+2; - tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ; - tables[0].db=tables[1].db=tables[2].db=thd->db; - if (simple_open_n_lock_tables(thd, tables)) - { - sql_print_error("Fatal error: Can't open and lock privilege tables: %s", - thd->net.last_error); - goto end; - } init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0); VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); @@ -453,19 +473,9 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables) init_check_host(); initialized=1; - thd->version--; // Force close to free memory return_val=0; end: - close_thread_tables(thd); - delete thd; - if (org_thd) - org_thd->store_globals(); /* purecov: inspected */ - else - { - /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); - } DBUG_RETURN(return_val); } @@ -489,27 +499,60 @@ void acl_free(bool end) /* - Forget current privileges and read new privileges from the privilege tables + Forget current user/db-level privileges and read new privileges + from the privilege tables. SYNOPSIS acl_reload() - thd Thread handle. Note that this may be NULL if we refresh - because we got a signal + thd Current thread + + NOTE + All tables of calling thread which were open and locked by LOCK TABLES + statement will be unlocked and closed. + This function is also used for initialization of structures responsible + for user/db-level privilege checking. + + RETURN VALUE + FALSE Success + TRUE Failure */ -void acl_reload(THD *thd) +my_bool acl_reload(THD *thd) { + TABLE_LIST tables[3]; DYNAMIC_ARRAY old_acl_hosts,old_acl_users,old_acl_dbs; MEM_ROOT old_mem; bool old_initialized; + my_bool return_val= 1; DBUG_ENTER("acl_reload"); - if (thd && thd->locked_tables) + if (thd->locked_tables) { // Can't have locked tables here thd->lock=thd->locked_tables; thd->locked_tables=0; close_thread_tables(thd); } + + /* + To avoid deadlocks we should obtain table locks before + obtaining acl_cache->lock mutex. + */ + bzero((char*) tables, sizeof(tables)); + tables[0].alias= tables[0].table_name= (char*) "host"; + tables[1].alias= tables[1].table_name= (char*) "user"; + tables[2].alias= tables[2].table_name= (char*) "db"; + tables[0].db=tables[1].db=tables[2].db=(char*) "mysql"; + tables[0].next_local= tables[0].next_global= tables+1; + tables[1].next_local= tables[1].next_global= tables+2; + tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ; + + if (simple_open_n_lock_tables(thd, tables)) + { + sql_print_error("Fatal error: Can't open and lock privilege tables: %s", + thd->net.last_error); + goto end; + } + if ((old_initialized=initialized)) VOID(pthread_mutex_lock(&acl_cache->lock)); @@ -520,7 +563,7 @@ void acl_reload(THD *thd) delete_dynamic(&acl_wild_hosts); hash_free(&acl_check_hosts); - if (acl_init(thd, 0)) + if ((return_val= acl_load(thd, tables))) { // Error. Revert to old list DBUG_PRINT("error",("Reverting to old privileges")); acl_free(); /* purecov: inspected */ @@ -539,7 +582,9 @@ void acl_reload(THD *thd) } if (old_initialized) VOID(pthread_mutex_unlock(&acl_cache->lock)); - DBUG_VOID_RETURN; +end: + close_thread_tables(thd); + DBUG_RETURN(return_val); } @@ -1329,7 +1374,13 @@ bool check_change_password(THD *thd, const char *host, const char *user, bool change_password(THD *thd, const char *host, const char *user, char *new_password) { + TABLE_LIST tables; + TABLE *table; + /* Buffer should be extended when password length is extended. */ + char buff[512]; + ulong query_length; uint new_password_len= strlen(new_password); + bool result= 1; DBUG_ENTER("change_password"); DBUG_PRINT("enter",("host: '%s' user: '%s' new_password: '%s'", host,user,new_password)); @@ -1338,40 +1389,69 @@ bool change_password(THD *thd, const char *host, const char *user, if (check_change_password(thd, host, user, new_password, new_password_len)) DBUG_RETURN(1); + bzero((char*) &tables, sizeof(tables)); + tables.alias= tables.table_name= (char*) "user"; + tables.db= (char*) "mysql"; + +#ifdef HAVE_REPLICATION + /* + GRANT and REVOKE are applied the slave in/exclusion rules as they are + some kind of updates to the mysql.% tables. + */ + if (thd->slave_thread && rpl_filter->is_on()) + { + /* + The tables must be marked "updating" so that tables_ok() takes them into + account in tests. It's ok to leave 'updating' set after tables_ok. + */ + tables.updating= 1; + /* Thanks to bzero, tables.next==0 */ + if (!thp->spcont || rpl_filter->tables_ok(thd, &tables))) + DBUG_RETURN(0); + } +#endif + + if (!(table= open_ltable(thd, &tables, TL_WRITE))) + DBUG_RETURN(1); + VOID(pthread_mutex_lock(&acl_cache->lock)); ACL_USER *acl_user; if (!(acl_user= find_acl_user(host, user, TRUE))) { VOID(pthread_mutex_unlock(&acl_cache->lock)); my_message(ER_PASSWORD_NO_MATCH, ER(ER_PASSWORD_NO_MATCH), MYF(0)); - DBUG_RETURN(1); + goto end; } /* update loaded acl entry: */ set_user_salt(acl_user, new_password, new_password_len); - if (update_user_table(thd, + if (update_user_table(thd, table, acl_user->host.hostname ? acl_user->host.hostname : "", acl_user->user ? acl_user->user : "", new_password, new_password_len)) { VOID(pthread_mutex_unlock(&acl_cache->lock)); /* purecov: deadcode */ - DBUG_RETURN(1); /* purecov: deadcode */ + goto end; } acl_cache->clear(1); // Clear locked hostname cache VOID(pthread_mutex_unlock(&acl_cache->lock)); - - char buff[512]; /* Extend with extended password length*/ - ulong query_length= - my_sprintf(buff, - (buff,"SET PASSWORD FOR \"%-.120s\"@\"%-.120s\"=\"%-.120s\"", - acl_user->user ? acl_user->user : "", - acl_user->host.hostname ? acl_user->host.hostname : "", - new_password)); - thd->clear_error(); - Query_log_event qinfo(thd, buff, query_length, 0, FALSE); - mysql_bin_log.write(&qinfo); - DBUG_RETURN(0); + result= 0; + if (mysql_bin_log.is_open()) + { + query_length= + my_sprintf(buff, + (buff,"SET PASSWORD FOR \"%-.120s\"@\"%-.120s\"=\"%-.120s\"", + acl_user->user ? acl_user->user : "", + acl_user->host.hostname ? acl_user->host.hostname : "", + new_password)); + thd->clear_error(); + Query_log_event qinfo(thd, buff, query_length, 0, FALSE); + mysql_bin_log.write(&qinfo); + } +end: + close_thread_tables(thd); + DBUG_RETURN(result); } @@ -1485,44 +1565,29 @@ bool hostname_requires_resolving(const char *hostname) return FALSE; } + /* - Update grants in the user and database privilege tables + Update record for user in mysql.user privilege table with new password. + + SYNOPSIS + update_user_table() + thd Thread handle + table Pointer to TABLE object for open mysql.user table + host/user Hostname/username pair identifying user for which + new password should be set + new_password New password + new_password_len Length of new password */ -static bool update_user_table(THD *thd, const char *host, const char *user, +static bool update_user_table(THD *thd, TABLE *table, + const char *host, const char *user, const char *new_password, uint new_password_len) { - TABLE_LIST tables; - TABLE *table; - bool error=1; char user_key[MAX_KEY_LENGTH]; + int error; DBUG_ENTER("update_user_table"); DBUG_PRINT("enter",("user: %s host: %s",user,host)); - bzero((char*) &tables,sizeof(tables)); - tables.alias=tables.table_name=(char*) "user"; - tables.db=(char*) "mysql"; - -#ifdef HAVE_REPLICATION - /* - GRANT and REVOKE are applied the slave in/exclusion rules as they are - some kind of updates to the mysql.% tables. - */ - if (thd->slave_thread && rpl_filter->is_on()) - { - /* - The tables must be marked "updating" so that tables_ok() takes them into - account in tests. It's ok to leave 'updating' set after tables_ok. - */ - tables.updating= 1; - /* Thanks to bzero, tables.next==0 */ - if (!(thd->spcont || rpl_filter->tables_ok(0, &tables))) - DBUG_RETURN(0); - } -#endif - - if (!(table=open_ltable(thd,&tables,TL_WRITE))) - DBUG_RETURN(1); /* purecov: deadcode */ table->field[0]->store(host,(uint) strlen(host), system_charset_info); table->field[1]->store(user,(uint) strlen(user), system_charset_info); key_copy((byte *) user_key, table->record[0], table->key_info, @@ -1542,13 +1607,9 @@ static bool update_user_table(THD *thd, const char *host, const char *user, if ((error=table->file->update_row(table->record[1],table->record[0]))) { table->file->print_error(error,MYF(0)); /* purecov: deadcode */ - goto end; /* purecov: deadcode */ + DBUG_RETURN(1); } - error=0; // Record updated - -end: - close_thread_tables(thd); - DBUG_RETURN(error); + DBUG_RETURN(0); } @@ -3125,17 +3186,59 @@ void grant_free(void) } -/* Init grant array if possible */ +/* + Initialize structures responsible for table/column-level privilege checking + and load information for them from tables in the 'mysql' database. + + SYNOPSIS + grant_init() -my_bool grant_init(THD *org_thd) + RETURN VALUES + 0 ok + 1 Could not initialize grant's +*/ + +my_bool grant_init() { THD *thd; - TABLE_LIST tables[3]; + my_bool return_val; + DBUG_ENTER("grant_init"); + + if (!(thd= new THD)) + DBUG_RETURN(1); /* purecov: deadcode */ + thd->store_globals(); + return_val= grant_reload(thd); + delete thd; + /* Remember that we don't have a THD */ + my_pthread_setspecific_ptr(THR_THD, 0); + DBUG_RETURN(return_val); +} + + +/* + Initialize structures responsible for table/column-level privilege + checking and load information about grants from open privilege tables. + + SYNOPSIS + grant_load() + thd Current thread + tables List containing open "mysql.tables_priv" and + "mysql.columns_priv" tables. + + RETURN VALUES + FALSE - success + TRUE - error +*/ + +static my_bool grant_load(TABLE_LIST *tables) +{ MEM_ROOT *memex_ptr; my_bool return_val= 1; TABLE *t_table, *c_table, *p_table; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; - DBUG_ENTER("grant_init"); + MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, + THR_MALLOC); + DBUG_ENTER("grant_load"); grant_option = FALSE; (void) hash_init(&column_priv_hash,system_charset_info, @@ -3149,34 +3252,12 @@ my_bool grant_init(THD *org_thd) 0,0); init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); - /* Don't do anything if running with --skip-grant */ - if (!initialized) - DBUG_RETURN(0); /* purecov: tested */ - - if (!(thd=new THD)) - DBUG_RETURN(1); /* purecov: deadcode */ - thd->store_globals(); - thd->db= my_strdup("mysql",MYF(0)); - thd->db_length=5; // Safety - bzero((char*) &tables, sizeof(tables)); - tables[0].alias=tables[0].table_name= (char*) "tables_priv"; - tables[1].alias=tables[1].table_name= (char*) "columns_priv"; - tables[2].alias=tables[2].table_name= (char*) "procs_priv"; - tables[0].next_local= tables[0].next_global= tables+1; - tables[1].next_local= tables[1].next_global= tables+2; - tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ; - tables[0].db=tables[1].db=tables[2].db=thd->db; - - if (simple_open_n_lock_tables(thd, tables)) - goto end; - t_table = tables[0].table; c_table = tables[1].table; p_table= tables[2].table; t_table->file->ha_index_init(0, 1); p_table->file->ha_index_init(0, 1); if (!t_table->file->index_first(t_table->record[0])) { - /* Will be restored by org_thd->store_globals() */ memex_ptr= &memex; my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); do @@ -3214,7 +3295,6 @@ my_bool grant_init(THD *org_thd) } if (!p_table->file->index_first(p_table->record[0])) { - /* Will be restored by org_thd->store_globals() */ memex_ptr= &memex; my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); do @@ -3274,40 +3354,58 @@ my_bool grant_init(THD *org_thd) end_unlock: t_table->file->ha_index_end(); p_table->file->ha_index_end(); - thd->version--; // Force close to free memory - -end: - close_thread_tables(thd); - delete thd; - if (org_thd) - org_thd->store_globals(); - else - { - /* Remember that we don't have a THD */ - my_pthread_setspecific_ptr(THR_THD, 0); - } + my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr); DBUG_RETURN(return_val); } /* - Reload grant array (table and column privileges) if possible + Reload information about table and column level privileges if possible. SYNOPSIS grant_reload() - thd Thread handler (can be NULL) + thd Current thread NOTES - Locked tables are checked by acl_init and doesn't have to be checked here + Locked tables are checked by acl_reload() and doesn't have to be checked + in this call. + This function is also used for initialization of structures responsible + for table/column-level privilege checking. + + RETURN VALUE + FALSE Success + TRUE Error */ -void grant_reload(THD *thd) +my_bool grant_reload(THD *thd) { + TABLE_LIST tables[3]; HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash; bool old_grant_option; MEM_ROOT old_mem; + my_bool return_val= 1; DBUG_ENTER("grant_reload"); + /* Don't do anything if running with --skip-grant-tables */ + if (!initialized) + DBUG_RETURN(0); + + bzero((char*) tables, sizeof(tables)); + tables[0].alias= tables[0].table_name= (char*) "tables_priv"; + tables[1].alias= tables[1].table_name= (char*) "columns_priv"; + tables[2].alias= tables[2].table_name= (char*) "procs_priv"; + tables[0].db= tables[1].db= tables[2].db= (char *) "mysql"; + tables[0].next_local= tables[0].next_global= tables+1; + tables[1].next_local= tables[1].next_global= tables+2; + tables[0].lock_type= tables[1].lock_type= tables[2].lock_type= TL_READ; + + /* + To avoid deadlocks we should obtain table locks before + obtaining LOCK_grant rwlock. + */ + if (simple_open_n_lock_tables(thd, tables)) + goto end; + rw_wrlock(&LOCK_grant); grant_version++; old_column_priv_hash= column_priv_hash; @@ -3316,7 +3414,7 @@ void grant_reload(THD *thd) old_grant_option= grant_option; old_mem= memex; - if (grant_init(thd)) + if ((return_val= grant_load(tables))) { // Error. Revert to old hash DBUG_PRINT("error",("Reverting to old privileges")); grant_free(); /* purecov: deadcode */ @@ -3334,7 +3432,9 @@ void grant_reload(THD *thd) free_root(&old_mem,MYF(0)); } rw_unlock(&LOCK_grant); - DBUG_VOID_RETURN; +end: + close_thread_tables(thd); + DBUG_RETURN(return_val); } diff --git a/sql/sql_acl.h b/sql/sql_acl.h index 5e62e7ce6e3..50aa35e8cc7 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -175,8 +175,8 @@ public: /* prototypes */ bool hostname_requires_resolving(const char *hostname); -my_bool acl_init(THD *thd, bool dont_read_acl_tables); -void acl_reload(THD *thd); +my_bool acl_init(bool dont_read_acl_tables); +my_bool acl_reload(THD *thd); void acl_free(bool end=0); ulong acl_get(const char *host, const char *ip, const char *user, const char *db, my_bool db_is_pattern); @@ -197,9 +197,9 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table, bool is_proc, List <LEX_USER> &user_list, ulong rights, bool revoke, bool no_error); ACL_USER *check_acl_user(LEX_USER *user_name, uint *acl_acl_userdx); -my_bool grant_init(THD *thd); +my_bool grant_init(); void grant_free(void); -void grant_reload(THD *thd); +my_bool grant_reload(THD *thd); bool check_grant(THD *thd, ulong want_access, TABLE_LIST *tables, uint show_command, uint number, bool dont_print_error); bool check_grant_column (THD *thd, GRANT_INFO *grant, diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index bd8f6aadcf9..9db651bb507 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -923,8 +923,7 @@ static int check_connection(THD *thd) DBUG_PRINT("info", ("IO layer change in progress...")); if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout)) { - DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", - pkt_len)); + DBUG_PRINT("error", ("Failed to accept new SSL connection")); inc_host_errors(&thd->remote.sin_addr); return(ER_HANDSHAKE_ERROR); } @@ -3472,7 +3471,7 @@ end_with_restore_list: if (lex->local_file) { if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) || - ! opt_local_infile) + !opt_local_infile) { my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); goto error; @@ -6557,8 +6556,25 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, #ifndef NO_EMBEDDED_ACCESS_CHECKS if (options & REFRESH_GRANT) { - acl_reload(thd); - grant_reload(thd); + THD *tmp_thd= 0; + /* + If reload_acl_and_cache() is called from SIGHUP handler we have to + allocate temporary THD for execution of acl_reload()/grant_reload(). + */ + if (!thd && (thd= (tmp_thd= new THD))) + thd->store_globals(); + if (thd) + { + (void)acl_reload(thd); + (void)grant_reload(thd); + } + if (tmp_thd) + { + delete tmp_thd; + /* Remember that we don't have a THD */ + my_pthread_setspecific_ptr(THR_THD, 0); + thd= 0; + } reset_mqh((LEX_USER *)NULL, TRUE); } #endif diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 48fadb781fb..573d5349471 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2529,11 +2529,16 @@ send_result_message: } default: // Probably HA_ADMIN_INTERNAL_ERROR - protocol->store("error", 5, system_charset_info); - protocol->store("Unknown - internal error during operation", 41 - , system_charset_info); - fatal_error=1; - break; + { + char buf[ERRMSGSIZE+20]; + uint length=my_snprintf(buf, ERRMSGSIZE, + "Unknown - internal error %d during operation", + result_code); + protocol->store("error", 5, system_charset_info); + protocol->store(buf, length, system_charset_info); + fatal_error=1; + break; + } } if (fatal_error) table->table->s->version=0; // Force close of table @@ -3951,7 +3956,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, Field **f_ptr,*field; for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++) { - /* Check if field should be droped */ + /* Check if field should be dropped */ Alter_drop *drop; drop_it.rewind(); while ((drop=drop_it++)) diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index bfe1748af01..7c0dd13b870 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -62,7 +62,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) } if (share->base.blobs) mi_alloc_rec_buff(info, -1, &info->rec_buff); -#if defined(HAVE_MMAP) && defined(HAVE_MADVICE) +#if defined(HAVE_MMAP) && defined(HAVE_MADVISE) if (info->opt_flag & MEMMAP_USED) madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM); #endif @@ -93,7 +93,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) my_errno=EACCES; break; } -#if defined(HAVE_MMAP) && defined(HAVE_MADVICE) +#if defined(HAVE_MMAP) && defined(HAVE_MADVISE) if ((share->options & HA_OPTION_COMPRESS_RECORD)) { pthread_mutex_lock(&share->intern_lock); @@ -177,7 +177,7 @@ int mi_extra(MI_INFO *info, enum ha_extra_function function, void *extra_arg) error=end_io_cache(&info->rec_cache); /* Sergei will insert full text index caching here */ } -#if defined(HAVE_MMAP) && defined(HAVE_MADVICE) +#if defined(HAVE_MMAP) && defined(HAVE_MADVISE) if (info->opt_flag & MEMMAP_USED) madvise(share->file_map,share->state.state.data_file_length,MADV_RANDOM); #endif diff --git a/storage/ndb/include/kernel/signaldata/FsRef.hpp b/storage/ndb/include/kernel/signaldata/FsRef.hpp index 650f6520fb5..2f7038de4ec 100644 --- a/storage/ndb/include/kernel/signaldata/FsRef.hpp +++ b/storage/ndb/include/kernel/signaldata/FsRef.hpp @@ -31,25 +31,7 @@ * SENDER: Ndbfs * RECIVER: */ -class FsRef { - /** - * Reciver(s) - */ - friend class Dbdict; - friend class Backup; - - /** - * Sender(s) - */ - friend class Ndbfs; - friend class VoidFs; - - /** - * For printing - */ - friend bool printFSREF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo); - -public: +struct FsRef { /** * Enum type for errorCode */ @@ -73,8 +55,6 @@ public: */ STATIC_CONST( SignalLength = 4 ); -private: - /** * DATA VARIABLES */ diff --git a/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp b/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp index eae72f43db5..2c36896e34c 100644 --- a/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp +++ b/storage/ndb/src/kernel/blocks/backup/BackupInit.cpp @@ -150,16 +150,16 @@ Backup::Backup(const Configuration & conf) : addRecSignal(GSN_DI_FCOUNTCONF, &Backup::execDI_FCOUNTCONF); addRecSignal(GSN_DIGETPRIMCONF, &Backup::execDIGETPRIMCONF); - addRecSignal(GSN_FSOPENREF, &Backup::execFSOPENREF); + addRecSignal(GSN_FSOPENREF, &Backup::execFSOPENREF, true); addRecSignal(GSN_FSOPENCONF, &Backup::execFSOPENCONF); - addRecSignal(GSN_FSCLOSEREF, &Backup::execFSCLOSEREF); + addRecSignal(GSN_FSCLOSEREF, &Backup::execFSCLOSEREF, true); addRecSignal(GSN_FSCLOSECONF, &Backup::execFSCLOSECONF); - addRecSignal(GSN_FSAPPENDREF, &Backup::execFSAPPENDREF); + addRecSignal(GSN_FSAPPENDREF, &Backup::execFSAPPENDREF, true); addRecSignal(GSN_FSAPPENDCONF, &Backup::execFSAPPENDCONF); - addRecSignal(GSN_FSREMOVEREF, &Backup::execFSREMOVEREF); + addRecSignal(GSN_FSREMOVEREF, &Backup::execFSREMOVEREF, true); addRecSignal(GSN_FSREMOVECONF, &Backup::execFSREMOVECONF); /*****/ diff --git a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp index 8d9c9bda892..708baefd0c0 100644 --- a/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp +++ b/storage/ndb/src/kernel/blocks/dbacc/Dbacc.hpp @@ -905,17 +905,12 @@ private: void execACC_TO_REQ(Signal* signal); void execACC_LOCKREQ(Signal* signal); void execFSOPENCONF(Signal* signal); - void execFSOPENREF(Signal* signal); void execFSCLOSECONF(Signal* signal); - void execFSCLOSEREF(Signal* signal); void execFSWRITECONF(Signal* signal); - void execFSWRITEREF(Signal* signal); void execFSREADCONF(Signal* signal); - void execFSREADREF(Signal* signal); void execNDB_STTOR(Signal* signal); void execDROP_TAB_REQ(Signal* signal); void execFSREMOVECONF(Signal* signal); - void execFSREMOVEREF(Signal* signal); void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDUMP_STATE_ORD(Signal* signal); diff --git a/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp b/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp index e735e3a372f..bd26c8f60e7 100644 --- a/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp +++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp @@ -188,17 +188,12 @@ Dbacc::Dbacc(const class Configuration & conf): addRecSignal(GSN_ACC_TO_REQ, &Dbacc::execACC_TO_REQ); addRecSignal(GSN_ACC_LOCKREQ, &Dbacc::execACC_LOCKREQ); addRecSignal(GSN_FSOPENCONF, &Dbacc::execFSOPENCONF); - addRecSignal(GSN_FSOPENREF, &Dbacc::execFSOPENREF); addRecSignal(GSN_FSCLOSECONF, &Dbacc::execFSCLOSECONF); - addRecSignal(GSN_FSCLOSEREF, &Dbacc::execFSCLOSEREF); addRecSignal(GSN_FSWRITECONF, &Dbacc::execFSWRITECONF); - addRecSignal(GSN_FSWRITEREF, &Dbacc::execFSWRITEREF); addRecSignal(GSN_FSREADCONF, &Dbacc::execFSREADCONF); - addRecSignal(GSN_FSREADREF, &Dbacc::execFSREADREF); addRecSignal(GSN_NDB_STTOR, &Dbacc::execNDB_STTOR); addRecSignal(GSN_DROP_TAB_REQ, &Dbacc::execDROP_TAB_REQ); addRecSignal(GSN_FSREMOVECONF, &Dbacc::execFSREMOVECONF); - addRecSignal(GSN_FSREMOVEREF, &Dbacc::execFSREMOVEREF); addRecSignal(GSN_READ_CONFIG_REQ, &Dbacc::execREAD_CONFIG_REQ, true); addRecSignal(GSN_SET_VAR_REQ, &Dbacc::execSET_VAR_REQ); diff --git a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index 1f070127936..0ae96cd1994 100644 --- a/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -251,15 +251,6 @@ void Dbacc::execFSCLOSECONF(Signal* signal) return; }//Dbacc::execFSCLOSECONF() -/* ******************--------------------------------------------------------------- */ -/* FSCLOSEREF OPENFILE CONF */ -/* ******************------------------------------+ */ -/* SENDER: FS, LEVEL B */ -void Dbacc::execFSCLOSEREF(Signal* signal) -{ - jamEntry(); - ndbrequire(false); -}//Dbacc::execFSCLOSEREF() /* ******************--------------------------------------------------------------- */ /* FSOPENCONF OPENFILE CONF */ @@ -307,15 +298,6 @@ void Dbacc::execFSOPENCONF(Signal* signal) return; }//Dbacc::execFSOPENCONF() -/* ******************--------------------------------------------------------------- */ -/* FSOPENREF OPENFILE REF */ -/* ******************------------------------------+ */ -/* SENDER: FS, LEVEL B */ -void Dbacc::execFSOPENREF(Signal* signal) -{ - jamEntry(); - ndbrequire(false); -}//Dbacc::execFSOPENREF() /* ******************--------------------------------------------------------------- */ /* FSREADCONF OPENFILE CONF */ @@ -369,16 +351,6 @@ void Dbacc::execFSREADCONF(Signal* signal) return; }//Dbacc::execFSREADCONF() -/* ******************--------------------------------------------------------------- */ -/* FSREADRREF OPENFILE CONF */ -/* ******************------------------------------+ */ -/* SENDER: FS, LEVEL B */ -void Dbacc::execFSREADREF(Signal* signal) -{ - jamEntry(); - progError(0, __LINE__, "Read of file refused"); - return; -}//Dbacc::execFSREADREF() /* ******************--------------------------------------------------------------- */ /* FSWRITECONF OPENFILE CONF */ @@ -482,16 +454,6 @@ void Dbacc::execFSWRITECONF(Signal* signal) return; }//Dbacc::execFSWRITECONF() -/* ******************--------------------------------------------------------------- */ -/* FSWRITEREF OPENFILE CONF */ -/* ******************------------------------------+ */ -/* SENDER: FS, LEVEL B */ -void Dbacc::execFSWRITEREF(Signal* signal) -{ - jamEntry(); - progError(0, __LINE__, "Write to file refused"); - return; -}//Dbacc::execFSWRITEREF() /* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */ @@ -1436,10 +1398,6 @@ void Dbacc::execFSREMOVECONF(Signal* signal) tabPtr.p->tabUserRef = 0; }//Dbacc::execFSREMOVECONF() -void Dbacc::execFSREMOVEREF(Signal* signal) -{ - ndbrequire(false); -}//Dbacc::execFSREMOVEREF() /* -------------------------------------------------------------------------- */ /* ADDFRAGTOTAB */ diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index bfd97c6e7d5..2059e992051 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -399,14 +399,6 @@ void Dbdict::execFSCLOSECONF(Signal* signal) }//switch }//execFSCLOSECONF() -/* ---------------------------------------------------------------- */ -// A close file was refused. -/* ---------------------------------------------------------------- */ -void Dbdict::execFSCLOSEREF(Signal* signal) -{ - jamEntry(); - progError(0, 0); -}//execFSCLOSEREF() /* ---------------------------------------------------------------- */ // A file was successfully opened. @@ -469,17 +461,21 @@ void Dbdict::execFSOPENREF(Signal* signal) c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer); switch (fsPtr.p->fsState) { case FsConnectRecord::OPEN_READ_SCHEMA1: + jam(); openReadSchemaRef(signal, fsPtr); - break; + return; case FsConnectRecord::OPEN_READ_TAB_FILE1: jam(); openReadTableRef(signal, fsPtr); - break; + return; default: - jamLine((fsPtr.p->fsState & 0xFFF)); - ndbrequire(false); break; }//switch + { + char msg[100]; + sprintf(msg, "File system open failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState); + fsRefError(signal,__LINE__,msg); + } }//execFSOPENREF() /* ---------------------------------------------------------------- */ @@ -519,17 +515,21 @@ void Dbdict::execFSREADREF(Signal* signal) c_fsConnectRecordPool.getPtr(fsPtr, fsRef->userPointer); switch (fsPtr.p->fsState) { case FsConnectRecord::READ_SCHEMA1: + jam(); readSchemaRef(signal, fsPtr); - break; + return; case FsConnectRecord::READ_TAB_FILE1: jam(); readTableRef(signal, fsPtr); - break; + return; default: - jamLine((fsPtr.p->fsState & 0xFFF)); - ndbrequire(false); break; }//switch + { + char msg[100]; + sprintf(msg, "File system read failed during FsConnectRecord state %d", (Uint32)fsPtr.p->fsState); + fsRefError(signal,__LINE__,msg); + } }//execFSREADREF() /* ---------------------------------------------------------------- */ @@ -556,14 +556,6 @@ void Dbdict::execFSWRITECONF(Signal* signal) }//switch }//execFSWRITECONF() -/* ---------------------------------------------------------------- */ -// A write file was refused. -/* ---------------------------------------------------------------- */ -void Dbdict::execFSWRITEREF(Signal* signal) -{ - jamEntry(); - progError(0, 0); -}//execFSWRITEREF() /* ---------------------------------------------------------------- */ // Routines to handle Read/Write of Table Files @@ -1326,13 +1318,11 @@ Dbdict::Dbdict(const class Configuration & conf): addRecSignal(GSN_DICTSTARTREQ, &Dbdict::execDICTSTARTREQ); addRecSignal(GSN_READ_NODESCONF, &Dbdict::execREAD_NODESCONF); addRecSignal(GSN_FSOPENCONF, &Dbdict::execFSOPENCONF); - addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF); + addRecSignal(GSN_FSOPENREF, &Dbdict::execFSOPENREF, true); addRecSignal(GSN_FSCLOSECONF, &Dbdict::execFSCLOSECONF); - addRecSignal(GSN_FSCLOSEREF, &Dbdict::execFSCLOSEREF); addRecSignal(GSN_FSWRITECONF, &Dbdict::execFSWRITECONF); - addRecSignal(GSN_FSWRITEREF, &Dbdict::execFSWRITEREF); addRecSignal(GSN_FSREADCONF, &Dbdict::execFSREADCONF); - addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF); + addRecSignal(GSN_FSREADREF, &Dbdict::execFSREADREF, true); addRecSignal(GSN_LQHFRAGCONF, &Dbdict::execLQHFRAGCONF); addRecSignal(GSN_LQHADDATTCONF, &Dbdict::execLQHADDATTCONF); addRecSignal(GSN_LQHADDATTREF, &Dbdict::execLQHADDATTREF); diff --git a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index b7f6fe03eb1..632bff0c8f7 100644 --- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -471,13 +471,11 @@ private: void execSCHEMA_INFOCONF(Signal* signal); void execREAD_NODESCONF(Signal* signal); void execFSCLOSECONF(Signal* signal); - void execFSCLOSEREF(Signal* signal); void execFSOPENCONF(Signal* signal); void execFSOPENREF(Signal* signal); void execFSREADCONF(Signal* signal); void execFSREADREF(Signal* signal); void execFSWRITECONF(Signal* signal); - void execFSWRITEREF(Signal* signal); void execNDB_STTOR(Signal* signal); void execREAD_CONFIG_REQ(Signal* signal); void execSTTOR(Signal* signal); diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp index 9a5efebc56e..1c14163fe76 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihInit.cpp @@ -206,13 +206,13 @@ Dbdih::Dbdih(const class Configuration & config): addRecSignal(GSN_ADD_FRAGCONF, &Dbdih::execADD_FRAGCONF); addRecSignal(GSN_ADD_FRAGREF, &Dbdih::execADD_FRAGREF); addRecSignal(GSN_FSOPENCONF, &Dbdih::execFSOPENCONF); - addRecSignal(GSN_FSOPENREF, &Dbdih::execFSOPENREF); + addRecSignal(GSN_FSOPENREF, &Dbdih::execFSOPENREF, true); addRecSignal(GSN_FSCLOSECONF, &Dbdih::execFSCLOSECONF); - addRecSignal(GSN_FSCLOSEREF, &Dbdih::execFSCLOSEREF); + addRecSignal(GSN_FSCLOSEREF, &Dbdih::execFSCLOSEREF, true); addRecSignal(GSN_FSREADCONF, &Dbdih::execFSREADCONF); - addRecSignal(GSN_FSREADREF, &Dbdih::execFSREADREF); + addRecSignal(GSN_FSREADREF, &Dbdih::execFSREADREF, true); addRecSignal(GSN_FSWRITECONF, &Dbdih::execFSWRITECONF); - addRecSignal(GSN_FSWRITEREF, &Dbdih::execFSWRITEREF); + addRecSignal(GSN_FSWRITEREF, &Dbdih::execFSWRITEREF, true); addRecSignal(GSN_SET_VAR_REQ, &Dbdih::execSET_VAR_REQ); addRecSignal(GSN_START_INFOREQ, diff --git a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index f6bec853a63..57af5ebec72 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -782,29 +782,36 @@ void Dbdih::execFSCLOSEREF(Signal* signal) filePtr.p->reqStatus = FileRecord::IDLE; switch (status) { case FileRecord::CLOSING_GCP: - ndbrequire(false); + jam(); break; case FileRecord::CLOSING_GCP_CRASH: jam(); closingGcpCrashLab(signal, filePtr); - break; + return; case FileRecord::CLOSING_TABLE_CRASH: jam(); closingTableCrashLab(signal, filePtr); - break; + return; case FileRecord::CLOSING_TABLE_SR: - ndbrequire(false); + jam(); break; case FileRecord::TABLE_CLOSE: - ndbrequire(false); + jam(); break; case FileRecord::TABLE_CLOSE_DELETE: - ndbrequire(false); + jam(); break; default: - ndbrequire(false); + jam(); break; + }//switch + { + char msg[100]; + sprintf(msg, "File system close failed during FileRecord status %d", (Uint32)status); + fsRefError(signal,__LINE__,msg); + } + return; }//Dbdih::execFSCLOSEREF() @@ -868,34 +875,39 @@ void Dbdih::execFSOPENREF(Signal* signal) /* WE DID NOT MANAGE TO CREATE A GLOBAL CHECKPOINT FILE. SERIOUS ERROR */ /* WHICH CAUSES A SYSTEM RESTART. */ /* --------------------------------------------------------------------- */ - ndbrequire(false); + jam(); break; case FileRecord::OPENING_COPY_GCI: jam(); openingCopyGciErrorLab(signal, filePtr); - break; + return; case FileRecord::CREATING_COPY_GCI: - ndbrequire(false); + jam(); break; case FileRecord::OPENING_GCP: jam(); openingGcpErrorLab(signal, filePtr); - break; + return; case FileRecord::OPENING_TABLE: jam(); openingTableErrorLab(signal, filePtr); - break; + return; case FileRecord::TABLE_CREATE: - ndbrequire(false); + jam(); break; case FileRecord::TABLE_OPEN_FOR_DELETE: jam(); tableDeleteLab(signal, filePtr); - break; + return; default: - ndbrequire(false); + jam(); break; }//switch + { + char msg[100]; + sprintf(msg, "File system open failed during FileRecord status %d", (Uint32)status); + fsRefError(signal,__LINE__,msg); + } return; }//Dbdih::execFSOPENREF() @@ -935,16 +947,19 @@ void Dbdih::execFSREADREF(Signal* signal) case FileRecord::READING_GCP: jam(); readingGcpErrorLab(signal, filePtr); - break; + return; case FileRecord::READING_TABLE: jam(); readingTableErrorLab(signal, filePtr); - break; + return; default: - ndbrequire(false); break; }//switch - return; + { + char msg[100]; + sprintf(msg, "File system read failed during FileRecord status %d", (Uint32)status); + fsRefError(signal,__LINE__,msg); + } }//Dbdih::execFSREADREF() void Dbdih::execFSWRITECONF(Signal* signal) @@ -989,22 +1004,27 @@ void Dbdih::execFSWRITEREF(Signal* signal) /* EVEN CREATING THE FILE DID NOT WORK. WE WILL THEN CRASH. */ /* ERROR IN WRITING FILE. WE WILL NOT CONTINUE FROM HERE. */ /* --------------------------------------------------------------------- */ - ndbrequire(false); + jam(); break; case FileRecord::WRITE_INIT_GCP: /* --------------------------------------------------------------------- */ /* AN ERROR OCCURRED IN WRITING A GCI FILE WHICH IS A SERIOUS ERROR */ /* THAT CAUSE A SYSTEM RESTART. */ /* --------------------------------------------------------------------- */ - ndbrequire(false); + jam(); break; case FileRecord::TABLE_WRITE: - ndbrequire(false); + jam(); break; default: - ndbrequire(false); + jam(); break; }//switch + { + char msg[100]; + sprintf(msg, "File system write failed during FileRecord status %d", (Uint32)status); + fsRefError(signal,__LINE__,msg); + } return; }//Dbdih::execFSWRITEREF() diff --git a/storage/ndb/src/kernel/blocks/dbdih/Makefile.am b/storage/ndb/src/kernel/blocks/dbdih/Makefile.am index 0b35884a586..1fe98a415be 100644 --- a/storage/ndb/src/kernel/blocks/dbdih/Makefile.am +++ b/storage/ndb/src/kernel/blocks/dbdih/Makefile.am @@ -1,10 +1,16 @@ noinst_LIBRARIES = libdbdih.a +EXTRA_PROGRAMS = ndbd_sysfile_reader libdbdih_a_SOURCES = DbdihInit.cpp DbdihMain.cpp +ndbd_sysfile_reader_SOURCES = printSysfile/printSysfile.cpp include $(top_srcdir)/storage/ndb/config/common.mk.am include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am +LDADD += \ + $(top_builddir)/ndb/src/common/util/libgeneral.la \ + $(top_builddir)/ndb/src/common/portlib/libportlib.la + # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index 95f510a5a60..040f839711b 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -2178,9 +2178,7 @@ private: void execTUP_SRREF(Signal* signal); void execGCP_SAVEREQ(Signal* signal); void execFSOPENCONF(Signal* signal); - void execFSOPENREF(Signal* signal); void execFSCLOSECONF(Signal* signal); - void execFSCLOSEREF(Signal* signal); void execFSWRITECONF(Signal* signal); void execFSWRITEREF(Signal* signal); void execFSREADCONF(Signal* signal); @@ -2189,7 +2187,6 @@ private: void execSET_VAR_REQ(Signal* signal); void execTIME_SIGNAL(Signal* signal); void execFSSYNCCONF(Signal* signal); - void execFSSYNCREF(Signal* signal); void execALTER_TAB_REQ(Signal* signal); void execALTER_TAB_CONF(Signal* signal); diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp index 0ef72bd35ad..13251df53bd 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhInit.cpp @@ -309,18 +309,15 @@ Dblqh::Dblqh(const class Configuration & conf): addRecSignal(GSN_TUP_SRREF, &Dblqh::execTUP_SRREF); addRecSignal(GSN_GCP_SAVEREQ, &Dblqh::execGCP_SAVEREQ); addRecSignal(GSN_FSOPENCONF, &Dblqh::execFSOPENCONF); - addRecSignal(GSN_FSOPENREF, &Dblqh::execFSOPENREF); addRecSignal(GSN_FSCLOSECONF, &Dblqh::execFSCLOSECONF); - addRecSignal(GSN_FSCLOSEREF, &Dblqh::execFSCLOSEREF); addRecSignal(GSN_FSWRITECONF, &Dblqh::execFSWRITECONF); - addRecSignal(GSN_FSWRITEREF, &Dblqh::execFSWRITEREF); + addRecSignal(GSN_FSWRITEREF, &Dblqh::execFSWRITEREF, true); addRecSignal(GSN_FSREADCONF, &Dblqh::execFSREADCONF); - addRecSignal(GSN_FSREADREF, &Dblqh::execFSREADREF); + addRecSignal(GSN_FSREADREF, &Dblqh::execFSREADREF, true); addRecSignal(GSN_ACC_ABORTCONF, &Dblqh::execACC_ABORTCONF); addRecSignal(GSN_SET_VAR_REQ, &Dblqh::execSET_VAR_REQ); addRecSignal(GSN_TIME_SIGNAL, &Dblqh::execTIME_SIGNAL); addRecSignal(GSN_FSSYNCCONF, &Dblqh::execFSSYNCCONF); - addRecSignal(GSN_FSSYNCREF, &Dblqh::execFSSYNCREF); addRecSignal(GSN_REMOVE_MARKER_ORD, &Dblqh::execREMOVE_MARKER_ORD); //addRecSignal(GSN_DROP_TAB_REQ, &Dblqh::execDROP_TAB_REQ); diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 502fd91b87b..4353d481d1a 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -11765,14 +11765,6 @@ Dblqh::execFSSYNCCONF(Signal* signal) ccurrentGcprec = RNIL; }//Dblqh::execFSSYNCCONF() -void -Dblqh::execFSSYNCREF(Signal* signal) -{ - jamEntry(); - systemErrorLab(signal); - return; -}//Dblqh::execFSSYNCREF() - /* ######################################################################### */ /* ####### FILE HANDLING MODULE ####### */ @@ -11843,16 +11835,6 @@ void Dblqh::execFSCLOSECONF(Signal* signal) }//switch }//Dblqh::execFSCLOSECONF() -/* ************>> */ -/* FSCLOSEREF > */ -/* ************>> */ -void Dblqh::execFSCLOSEREF(Signal* signal) -{ - jamEntry(); - terrorCode = signal->theData[1]; - systemErrorLab(signal); - return; -}//Dblqh::execFSCLOSEREF() /* ************>> */ /* FSOPENCONF > */ @@ -11941,16 +11923,6 @@ void Dblqh::execFSOPENCONF(Signal* signal) }//switch }//Dblqh::execFSOPENCONF() -/* ************> */ -/* FSOPENREF > */ -/* ************> */ -void Dblqh::execFSOPENREF(Signal* signal) -{ - jamEntry(); - terrorCode = signal->theData[1]; - systemErrorLab(signal); - return; -}//Dblqh::execFSOPENREF() /* ************>> */ /* FSREADCONF > */ @@ -12028,60 +12000,43 @@ void Dblqh::execFSREADREF(Signal* signal) jamEntry(); lfoPtr.i = signal->theData[0]; ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord); - terrorCode = signal->theData[1]; switch (lfoPtr.p->lfoState) { case LogFileOperationRecord::READ_SR_LAST_MBYTE: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_SR_FRONTPAGE: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_SR_LAST_FILE: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_SR_NEXT_FILE: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_EXEC_SR: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_EXEC_LOG: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_SR_FOURTH_PHASE: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_SR_FOURTH_ZERO: jam(); - systemErrorLab(signal); - return; break; case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES: jam() - systemErrorLab(signal); - return; break; default: jam(); - systemErrorLab(signal); - return; break; }//switch - return; + { + char msg[100]; + sprintf(msg, "File system read failed during LogFileOperationRecord state %d", (Uint32)lfoPtr.p->lfoState); + fsRefError(signal,__LINE__,msg); + } }//Dblqh::execFSREADREF() /* *************** */ @@ -12162,49 +12117,43 @@ void Dblqh::execFSWRITEREF(Signal* signal) switch (lfoPtr.p->lfoState) { case LogFileOperationRecord::WRITE_PAGE_ZERO: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::LAST_WRITE_IN_FILE: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::INIT_WRITE_AT_END: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::INIT_FIRST_PAGE: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::WRITE_GCI_ZERO: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::WRITE_DIRTY: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::WRITE_INIT_MBYTE: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::ACTIVE_WRITE_LOG: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE: jam(); - systemErrorLab(signal); break; case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES: jam(); systemErrorLab(signal); - break; default: jam(); - systemErrorLab(signal); break; }//switch + { + char msg[100]; + sprintf(msg, "File system write failed during LogFileOperationRecord state %d", (Uint32)lfoPtr.p->lfoState); + fsRefError(signal,__LINE__,msg); + } }//Dblqh::execFSWRITEREF() diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp index 63c271d6b80..ba6d65ca838 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp @@ -239,6 +239,17 @@ bool PageHeader::check() { return true; } +bool PageHeader::lastPage() +{ + return m_next_page == 0xffffff00; +} + +Uint32 PageHeader::lastWord() +{ + return m_current_page_index; +} + + NdbOut& operator<<(NdbOut& no, const PageHeader& ph) { no << "------------PAGE HEADER------------------------" << endl << endl; ndbout_c("%-30s%-12s%-12s\n", "", "Decimal", "Hex"); diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp index 27f2399abbe..11b8dc4a6fa 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp +++ b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp @@ -132,6 +132,8 @@ class PageHeader { public: bool check(); Uint32 getLogRecordSize(); + bool lastPage(); + Uint32 lastWord(); protected: Uint32 m_checksum; Uint32 m_lap; diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp index cea05aebc64..aa8b1d25e4e 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/redoLogFileReader.cpp @@ -35,7 +35,6 @@ #define FROM_BEGINNING 0 void usage(const char * prg); -Uint32 readRecordOverPageBoundary (Uint32 *, Uint32 , Uint32 , Uint32); Uint32 readFromFile(FILE * f, Uint32 *toPtr, Uint32 sizeInWords); void readArguments(int argc, const char** argv); void doExit(); @@ -54,8 +53,8 @@ Uint32 startAtPageIndex = 0; Uint32 *redoLogPage; NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read a redo log file", 16384) { - Uint32 pageIndex = 0; - Uint32 oldPageIndex = 0; + int wordIndex = 0; + int oldWordIndex = 0; Uint32 recordType = 1234567890; PageHeader *thePageHeader; @@ -83,48 +82,47 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read } redoLogPage = new Uint32[PAGESIZE*NO_PAGES_IN_MBYTE]; + Uint32 words_from_previous_page = 0; // Loop for every mbyte. - for (Uint32 j = startAtMbyte; j < NO_MBYTE_IN_FILE; j++) { + bool lastPage = false; + for (Uint32 j = startAtMbyte; j < NO_MBYTE_IN_FILE && !lastPage; j++) { + readFromFile(f, redoLogPage, PAGESIZE*NO_PAGES_IN_MBYTE); - - if (firstLap) { - pageIndex = startAtPageIndex; - firstLap = false; - } else - pageIndex = 0; - // Loop for every page. - for (int i = startAtPage; i < NO_PAGES_IN_MBYTE; i++) { - - if (pageIndex == 0) { - thePageHeader = (PageHeader *) &redoLogPage[i*PAGESIZE]; - // Print out mbyte number, page number and page index. - ndbout << j << ":" << i << ":" << pageIndex << endl - << " " << j*32 + i << ":" << pageIndex << " "; - if (thePrintFlag) ndbout << (*thePageHeader); - if (theCheckFlag) { - if(!thePageHeader->check()) { - ndbout << "Error in thePageHeader->check()" << endl; - doExit(); - } + words_from_previous_page = 0; - Uint32 checkSum = 37; - for (int ps = 1; ps < PAGESIZE; ps++) - checkSum = redoLogPage[i*PAGESIZE+ps] ^ checkSum; + // Loop for every page. + for (int i = 0; i < NO_PAGES_IN_MBYTE; i++) { + wordIndex = 0; + thePageHeader = (PageHeader *) &redoLogPage[i*PAGESIZE]; + // Print out mbyte number, page number and page index. + ndbout << j << ":" << i << ":" << wordIndex << endl + << " " << j*32 + i << ":" << wordIndex << " "; + if (thePrintFlag) ndbout << (*thePageHeader); + if (theCheckFlag) { + if(!thePageHeader->check()) { + ndbout << "Error in thePageHeader->check()" << endl; + doExit(); + } - if (checkSum != redoLogPage[i*PAGESIZE]){ - ndbout << "WRONG CHECKSUM: checksum = " << redoLogPage[i*PAGESIZE] - << " expected = " << checkSum << endl; - doExit(); - } - else - ndbout << "expected checksum: " << checkSum << endl; + Uint32 checkSum = 37; + for (int ps = 1; ps < PAGESIZE; ps++) + checkSum = redoLogPage[i*PAGESIZE+ps] ^ checkSum; + if (checkSum != redoLogPage[i*PAGESIZE]){ + ndbout << "WRONG CHECKSUM: checksum = " << redoLogPage[i*PAGESIZE] + << " expected = " << checkSum << endl; + doExit(); } - pageIndex += thePageHeader->getLogRecordSize(); + else + ndbout << "expected checksum: " << checkSum << endl; + } + lastPage = i != 0 && thePageHeader->lastPage(); + Uint32 lastWord = thePageHeader->lastWord(); + if (onlyMbyteHeaders) { // Show only the first page header in every mbyte of the file. break; @@ -132,18 +130,40 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read if (onlyPageHeaders) { // Show only page headers. Continue with the next page in this for loop. - pageIndex = 0; continue; } + + wordIndex = thePageHeader->getLogRecordSize() - words_from_previous_page; + Uint32 *redoLogPagePos = redoLogPage + i*PAGESIZE; + if (words_from_previous_page) + { + memmove(redoLogPagePos + wordIndex , + redoLogPagePos - words_from_previous_page, + words_from_previous_page*4); + } + do { - // Print out mbyte number, page number and page index. - ndbout << j << ":" << i << ":" << pageIndex << endl - << " " << j*32 + i << ":" << pageIndex << " "; - recordType = redoLogPage[i*PAGESIZE + pageIndex]; + if (words_from_previous_page) + { + // Print out mbyte number, page number and word index. + ndbout << j << ":" << i-1 << ":" << PAGESIZE-words_from_previous_page << endl + << j << ":" << i << ":" << wordIndex+words_from_previous_page << endl + << " " << j*32 + i-1 << ":" << PAGESIZE-words_from_previous_page << " "; + words_from_previous_page = 0; + } + else + { + // Print out mbyte number, page number and word index. + ndbout << j << ":" << i << ":" << wordIndex << endl + << " " << j*32 + i << ":" << wordIndex << " "; + } + redoLogPagePos = redoLogPage + i*PAGESIZE + wordIndex; + oldWordIndex = wordIndex; + recordType = *redoLogPagePos; switch(recordType) { case ZFD_TYPE: - fdRecord = (FileDescriptor *) &redoLogPage[i*PAGESIZE + pageIndex]; + fdRecord = (FileDescriptor *) redoLogPagePos; if (thePrintFlag) ndbout << (*fdRecord); if (theCheckFlag) { if(!fdRecord->check()) { @@ -155,13 +175,13 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read delete [] redoLogPage; exit(RETURN_OK); } - pageIndex += fdRecord->getLogRecordSize(); + wordIndex += fdRecord->getLogRecordSize(); break; case ZNEXT_LOG_RECORD_TYPE: - nlRecord = (NextLogRecord *) (&redoLogPage[i*PAGESIZE] + pageIndex); - pageIndex += nlRecord->getLogRecordSize(pageIndex); - if (pageIndex <= PAGESIZE) { + nlRecord = (NextLogRecord *) redoLogPagePos; + wordIndex += nlRecord->getLogRecordSize(wordIndex); + if (wordIndex <= PAGESIZE) { if (thePrintFlag) ndbout << (*nlRecord); if (theCheckFlag) { if(!nlRecord->check()) { @@ -173,9 +193,9 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read break; case ZCOMPLETED_GCI_TYPE: - cGCIrecord = (CompletedGCIRecord *) &redoLogPage[i*PAGESIZE + pageIndex]; - pageIndex += cGCIrecord->getLogRecordSize(); - if (pageIndex <= PAGESIZE) { + cGCIrecord = (CompletedGCIRecord *) redoLogPagePos; + wordIndex += cGCIrecord->getLogRecordSize(); + if (wordIndex <= PAGESIZE) { if (thePrintFlag) ndbout << (*cGCIrecord); if (theCheckFlag) { if(!cGCIrecord->check()) { @@ -187,9 +207,9 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read break; case ZPREP_OP_TYPE: - poRecord = (PrepareOperationRecord *) &redoLogPage[i*PAGESIZE + pageIndex]; - pageIndex += poRecord->getLogRecordSize(); - if (pageIndex <= PAGESIZE) { + poRecord = (PrepareOperationRecord *) redoLogPagePos; + wordIndex += poRecord->getLogRecordSize(); + if (wordIndex <= PAGESIZE) { if (thePrintFlag) ndbout << (*poRecord); if (theCheckFlag) { if(!poRecord->check()) { @@ -198,15 +218,12 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read } } } - else { - oldPageIndex = pageIndex - poRecord->getLogRecordSize(); - } break; case ZCOMMIT_TYPE: - ctRecord = (CommitTransactionRecord *) &redoLogPage[i*PAGESIZE + pageIndex]; - pageIndex += ctRecord->getLogRecordSize(); - if (pageIndex <= PAGESIZE) { + ctRecord = (CommitTransactionRecord *) redoLogPagePos; + wordIndex += ctRecord->getLogRecordSize(); + if (wordIndex <= PAGESIZE) { if (thePrintFlag) ndbout << (*ctRecord); if (theCheckFlag) { if(!ctRecord->check()) { @@ -215,15 +232,12 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read } } } - else { - oldPageIndex = pageIndex - ctRecord->getLogRecordSize(); - } break; case ZINVALID_COMMIT_TYPE: - ictRecord = (InvalidCommitTransactionRecord *) &redoLogPage[i*PAGESIZE + pageIndex]; - pageIndex += ictRecord->getLogRecordSize(); - if (pageIndex <= PAGESIZE) { + ictRecord = (InvalidCommitTransactionRecord *) redoLogPagePos; + wordIndex += ictRecord->getLogRecordSize(); + if (wordIndex <= PAGESIZE) { if (thePrintFlag) ndbout << (*ictRecord); if (theCheckFlag) { if(!ictRecord->check()) { @@ -232,21 +246,18 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read } } } - else { - oldPageIndex = pageIndex - ictRecord->getLogRecordSize(); - } break; case ZNEXT_MBYTE_TYPE: - nmRecord = (NextMbyteRecord *) &redoLogPage[i*PAGESIZE + pageIndex]; + nmRecord = (NextMbyteRecord *) redoLogPagePos; if (thePrintFlag) ndbout << (*nmRecord); i = NO_PAGES_IN_MBYTE; break; case ZABORT_TYPE: - atRecord = (AbortTransactionRecord *) &redoLogPage[i*PAGESIZE + pageIndex]; - pageIndex += atRecord->getLogRecordSize(); - if (pageIndex <= PAGESIZE) { + atRecord = (AbortTransactionRecord *) redoLogPagePos; + wordIndex += atRecord->getLogRecordSize(); + if (wordIndex <= PAGESIZE) { if (thePrintFlag) ndbout << (*atRecord); if (theCheckFlag) { if(!atRecord->check()) { @@ -266,7 +277,7 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read ndbout << " ------ERROR: UNKNOWN RECORD TYPE------" << endl; // Print out remaining data in this page - for (int j = pageIndex; j < PAGESIZE; j++){ + for (int j = wordIndex; j < PAGESIZE; j++){ Uint32 unknown = redoLogPage[i*PAGESIZE + j]; ndbout_c("%-30d%-12u%-12x", j, unknown, unknown); @@ -274,14 +285,18 @@ NDB_COMMAND(redoLogFileReader, "redoLogFileReader", "redoLogFileReader", "Read doExit(); } - } while(pageIndex < PAGESIZE && i < NO_PAGES_IN_MBYTE); + } while(wordIndex < lastWord && i < NO_PAGES_IN_MBYTE); + - if (pageIndex > PAGESIZE) { - // The last record overlapped page boundary. Must redo that record. - pageIndex = readRecordOverPageBoundary(&redoLogPage[i*PAGESIZE], - pageIndex, oldPageIndex, recordType); + if (lastPage) + break; + + if (wordIndex > PAGESIZE) { + words_from_previous_page = PAGESIZE - oldWordIndex; + ndbout << " ----------- Record continues on next page -----------" << endl; } else { - pageIndex = 0; + wordIndex = 0; + words_from_previous_page = 0; } ndbout << endl; }//for @@ -314,93 +329,6 @@ Uint32 readFromFile(FILE * f, Uint32 *toPtr, Uint32 sizeInWords) { // //---------------------------------------------------------------- -Uint32 readRecordOverPageBoundary(Uint32 *pagePtr, Uint32 pageIndex, Uint32 oldPageIndex, Uint32 recordType) { - Uint32 pageHeader[PAGEHEADERSIZE]; - Uint32 tmpPages[PAGESIZE*10]; - PageHeader *thePageHeader; - Uint32 recordSize = 0; - - PrepareOperationRecord *poRecord; - CommitTransactionRecord *ctRecord; - InvalidCommitTransactionRecord *ictRecord; - - memcpy(pageHeader, pagePtr + PAGESIZE, PAGEHEADERSIZE*sizeof(Uint32)); - memcpy(tmpPages, pagePtr + oldPageIndex, (PAGESIZE - oldPageIndex)*sizeof(Uint32)); - memcpy(tmpPages + PAGESIZE - oldPageIndex , - (pagePtr + PAGESIZE + PAGEHEADERSIZE), - (PAGESIZE - PAGEHEADERSIZE)*sizeof(Uint32)); - - switch(recordType) { - case ZPREP_OP_TYPE: - poRecord = (PrepareOperationRecord *) tmpPages; - recordSize = poRecord->getLogRecordSize(); - if (recordSize < (PAGESIZE - PAGEHEADERSIZE)) { - if (theCheckFlag) { - if(!poRecord->check()) { - ndbout << "Error in poRecord->check() (readRecordOverPageBoundary)" << endl; - doExit(); - } - } - if (thePrintFlag) ndbout << (*poRecord); - } else { - ndbout << "Error: Record greater than a Page" << endl; - } - break; - - case ZCOMMIT_TYPE: - ctRecord = (CommitTransactionRecord *) tmpPages; - recordSize = ctRecord->getLogRecordSize(); - if (recordSize < (PAGESIZE - PAGEHEADERSIZE)) { - if (theCheckFlag) { - if(!ctRecord->check()) { - ndbout << "Error in ctRecord->check() (readRecordOverPageBoundary)" << endl; - doExit(); - } - } - if (thePrintFlag) ndbout << (*ctRecord); - } else { - ndbout << endl << "Error: Record greater than a Page" << endl; - } - break; - - case ZINVALID_COMMIT_TYPE: - ictRecord = (InvalidCommitTransactionRecord *) tmpPages; - recordSize = ictRecord->getLogRecordSize(); - if (recordSize < (PAGESIZE - PAGEHEADERSIZE)) { - if (theCheckFlag) { - if(!ictRecord->check()) { - ndbout << "Error in ictRecord->check() (readRecordOverPageBoundary)" << endl; - doExit(); - } - } - if (thePrintFlag) ndbout << (*ictRecord); - } else { - ndbout << endl << "Error: Record greater than a Page" << endl; - } - break; - - case ZNEW_PREP_OP_TYPE: - case ZABORT_TYPE: - case ZFRAG_SPLIT_TYPE: - case ZNEXT_MBYTE_TYPE: - ndbout << endl << "Record type = " << recordType << " not implemented." << endl; - return 0; - - default: - ndbout << endl << "Error: Unknown record type. Record type = " << recordType << endl; - return 0; - } - - thePageHeader = (PageHeader *) (pagePtr + PAGESIZE); - if (thePrintFlag) ndbout << (*thePageHeader); - - return PAGEHEADERSIZE - PAGESIZE + oldPageIndex + recordSize; -} - -//---------------------------------------------------------------- -// -//---------------------------------------------------------------- - void usage(const char * prg){ ndbout << endl << "Usage: " << endl << prg diff --git a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index e4dc2fcf2ee..f0480853c1a 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -1108,20 +1108,15 @@ private: void execTUP_SRREQ(Signal* signal); void execTUP_PREPLCPREQ(Signal* signal); void execFSOPENCONF(Signal* signal); - void execFSOPENREF(Signal* signal); void execFSCLOSECONF(Signal* signal); - void execFSCLOSEREF(Signal* signal); void execFSWRITECONF(Signal* signal); - void execFSWRITEREF(Signal* signal); void execFSREADCONF(Signal* signal); - void execFSREADREF(Signal* signal); void execNDB_STTOR(Signal* signal); void execREAD_CONFIG_REQ(Signal* signal); void execSET_VAR_REQ(Signal* signal); void execDROP_TAB_REQ(Signal* signal); void execALTER_TAB_REQ(Signal* signal); void execFSREMOVECONF(Signal* signal); - void execFSREMOVEREF(Signal* signal); void execTUP_ALLOCREQ(Signal* signal); void execTUP_DEALLOCREQ(Signal* signal); void execTUP_WRITELOG_REQ(Signal* signal); diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index f02a804aa83..52ac96bc5d3 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -25,7 +25,6 @@ #include <AttributeHeader.hpp> #include <Interpreter.hpp> #include <signaldata/FsConf.hpp> -#include <signaldata/FsRef.hpp> #include <signaldata/FsRemoveReq.hpp> #include <signaldata/TupCommit.hpp> #include <signaldata/TupKey.hpp> @@ -117,13 +116,9 @@ Dbtup::Dbtup(const class Configuration & conf) addRecSignal(GSN_TUP_SRREQ, &Dbtup::execTUP_SRREQ); addRecSignal(GSN_TUP_PREPLCPREQ, &Dbtup::execTUP_PREPLCPREQ); addRecSignal(GSN_FSOPENCONF, &Dbtup::execFSOPENCONF); - addRecSignal(GSN_FSOPENREF, &Dbtup::execFSOPENREF); addRecSignal(GSN_FSCLOSECONF, &Dbtup::execFSCLOSECONF); - addRecSignal(GSN_FSCLOSEREF, &Dbtup::execFSCLOSEREF); addRecSignal(GSN_FSWRITECONF, &Dbtup::execFSWRITECONF); - addRecSignal(GSN_FSWRITEREF, &Dbtup::execFSWRITEREF); addRecSignal(GSN_FSREADCONF, &Dbtup::execFSREADCONF); - addRecSignal(GSN_FSREADREF, &Dbtup::execFSREADREF); addRecSignal(GSN_NDB_STTOR, &Dbtup::execNDB_STTOR); addRecSignal(GSN_READ_CONFIG_REQ, &Dbtup::execREAD_CONFIG_REQ, true); addRecSignal(GSN_SET_VAR_REQ, &Dbtup::execSET_VAR_REQ); @@ -133,7 +128,6 @@ Dbtup::Dbtup(const class Configuration & conf) addRecSignal(GSN_DROP_TRIG_REQ, &Dbtup::execDROP_TRIG_REQ); addRecSignal(GSN_DROP_TAB_REQ, &Dbtup::execDROP_TAB_REQ); - addRecSignal(GSN_FSREMOVEREF, &Dbtup::execFSREMOVEREF); addRecSignal(GSN_FSREMOVECONF, &Dbtup::execFSREMOVECONF); addRecSignal(GSN_TUP_ALLOCREQ, &Dbtup::execTUP_ALLOCREQ); @@ -268,12 +262,6 @@ void Dbtup::execFSCLOSECONF(Signal* signal) releasePendingFileOpenInfoRecord(pfoPtr); }//Dbtup::execFSCLOSECONF() -void Dbtup::execFSCLOSEREF(Signal* signal) -{ - ljamEntry(); - ndbrequire(false); -}//Dbtup::execFSCLOSEREF() - void Dbtup::execFSOPENCONF(Signal* signal) { PendingFileOpenInfoPtr pfoPtr; @@ -368,12 +356,6 @@ void Dbtup::execFSOPENCONF(Signal* signal) releasePendingFileOpenInfoRecord(pfoPtr); }//Dbtup::execFSOPENCONF() -void Dbtup::execFSOPENREF(Signal* signal) -{ - ljamEntry(); - ndbrequire(false); -}//Dbtup::execFSOPENREF() - void Dbtup::execFSREADCONF(Signal* signal) { DiskBufferSegmentInfoPtr dbsiPtr; @@ -429,12 +411,6 @@ void Dbtup::execFSREADCONF(Signal* signal) }//switch }//Dbtup::execFSREADCONF() -void Dbtup::execFSREADREF(Signal* signal) -{ - ljamEntry(); - ndbrequire(false); -}//Dbtup::execFSREADREF() - void Dbtup::execFSWRITECONF(Signal* signal) { DiskBufferSegmentInfoPtr dbsiPtr; @@ -483,12 +459,6 @@ void Dbtup::execFSWRITECONF(Signal* signal) return; }//Dbtup::execFSWRITECONF() -void Dbtup::execFSWRITEREF(Signal* signal) -{ - ljamEntry(); - ndbrequire(false); -}//Dbtup::execFSWRITEREF() - void Dbtup::execCONTINUEB(Signal* signal) { ljamEntry(); diff --git a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index 4ce807528c4..bacba2a880c 100644 --- a/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -702,10 +702,3 @@ void Dbtup::execFSREMOVECONF(Signal* signal) initTab(tabPtr.p); }//Dbtup::execFSREMOVECONF() -void Dbtup::execFSREMOVEREF(Signal* signal) -{ - ljamEntry(); - ndbrequire(false); -}//Dbtup::execFSREMOVEREF() - - diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp b/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp index 639d300d6df..657133bda36 100644 --- a/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp +++ b/storage/ndb/src/kernel/blocks/ndbcntr/Ndbcntr.hpp @@ -309,7 +309,6 @@ private: Uint32 c_fsRemoveCount; Uint32 c_nodeGroup; void clearFilesystem(Signal* signal); - void execFSREMOVEREF(Signal* signal); void execFSREMOVECONF(Signal* signal); NdbNodeBitmask c_allDefinedNodes; diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp index c7b472fc91a..97ca3f44b3a 100644 --- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp +++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrInit.cpp @@ -100,7 +100,6 @@ Ndbcntr::Ndbcntr(const class Configuration & conf): addRecSignal(GSN_STTORRY, &Ndbcntr::execSTTORRY); addRecSignal(GSN_READ_CONFIG_CONF, &Ndbcntr::execREAD_CONFIG_CONF); - addRecSignal(GSN_FSREMOVEREF, &Ndbcntr::execFSREMOVEREF); addRecSignal(GSN_FSREMOVECONF, &Ndbcntr::execFSREMOVECONF); initData(); diff --git a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index c837321a52d..6f28bb03537 100644 --- a/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -144,6 +144,7 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) const SystemError * const sysErr = (SystemError *)signal->getDataPtr(); char buf[100]; int killingNode = refToNode(sysErr->errorRef); + Uint32 data1 = sysErr->data1; jamEntry(); switch (sysErr->errorCode){ @@ -178,8 +179,9 @@ void Ndbcntr::execSYSTEM_ERROR(Signal* signal) case SystemError::CopyFragRefError: BaseString::snprintf(buf, sizeof(buf), "Node %d killed this node because " - "it could not copy a fragment during node restart", - killingNode); + "it could not copy a fragment during node restart. " + "Copy fragment error code: %u.", + killingNode, data1); break; default: @@ -2392,12 +2394,6 @@ Ndbcntr::clearFilesystem(Signal* signal){ } void -Ndbcntr::execFSREMOVEREF(Signal* signal){ - jamEntry(); - ndbrequire(0); -} - -void Ndbcntr::execFSREMOVECONF(Signal* signal){ jamEntry(); if(c_fsRemoveCount == 13){ diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp index ef9f2c3c716..57a4032e40b 100644 --- a/storage/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/storage/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -29,6 +29,7 @@ #include <signaldata/EventReport.hpp> #include <signaldata/ContinueFragmented.hpp> #include <signaldata/NodeStateSignalData.hpp> +#include <signaldata/FsRef.hpp> #include <DebuggerNames.hpp> #include "LongSignal.hpp" @@ -140,6 +141,13 @@ SimulatedBlock::installSimulatedBlockFunctions(){ a[GSN_UTIL_UNLOCK_REF] = &SimulatedBlock::execUTIL_UNLOCK_REF; a[GSN_UTIL_UNLOCK_CONF] = &SimulatedBlock::execUTIL_UNLOCK_CONF; a[GSN_READ_CONFIG_REQ] = &SimulatedBlock::execREAD_CONFIG_REQ; + a[GSN_FSOPENREF] = &SimulatedBlock::execFSOPENREF; + a[GSN_FSCLOSEREF] = &SimulatedBlock::execFSCLOSEREF; + a[GSN_FSWRITEREF] = &SimulatedBlock::execFSWRITEREF; + a[GSN_FSREADREF] = &SimulatedBlock::execFSREADREF; + a[GSN_FSREMOVEREF] = &SimulatedBlock::execFSREMOVEREF; + a[GSN_FSSYNCREF] = &SimulatedBlock::execFSSYNCREF; + a[GSN_FSAPPENDREF] = &SimulatedBlock::execFSAPPENDREF; } void @@ -1781,6 +1789,61 @@ SimulatedBlock::execUPGRADE(Signal* signal){ } } +void +SimulatedBlock::fsRefError(Signal* signal, Uint32 line, const char *msg) +{ + const FsRef *fsRef = (FsRef*)signal->getDataPtr(); + Uint32 errorCode = fsRef->errorCode; + Uint32 osErrorCode = fsRef->osErrorCode; + char msg2[100]; + + sprintf(msg2, "%s: %s. OS errno: %u", getBlockName(number()), msg, osErrorCode); + + progError(line, errorCode, msg2); +} + +void +SimulatedBlock::execFSWRITEREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system write failed"); +} + +void +SimulatedBlock::execFSREADREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system read failed"); +} + +void +SimulatedBlock::execFSCLOSEREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system close failed"); +} + +void +SimulatedBlock::execFSOPENREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system open failed"); +} + +void +SimulatedBlock::execFSREMOVEREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system remove failed"); +} + +void +SimulatedBlock::execFSSYNCREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system sync failed"); +} + +void +SimulatedBlock::execFSAPPENDREF(Signal* signal) +{ + fsRefError(signal, __LINE__, "File system append failed"); +} + #ifdef VM_TRACE void SimulatedBlock::clear_global_variables(){ diff --git a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp index 50c85a0b274..bba92ca7c31 100644 --- a/storage/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/storage/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -507,6 +507,15 @@ private: protected: void execUPGRADE(Signal* signal); + void fsRefError(Signal* signal, Uint32 line, const char *msg); + void execFSWRITEREF(Signal* signal); + void execFSREADREF(Signal* signal); + void execFSOPENREF(Signal* signal); + void execFSCLOSEREF(Signal* signal); + void execFSREMOVEREF(Signal* signal); + void execFSSYNCREF(Signal* signal); + void execFSAPPENDREF(Signal* signal); + // Variable for storing inserted errors, see pc.H ERROR_INSERT_VARIABLE; diff --git a/storage/ndb/src/mgmclient/CommandInterpreter.cpp b/storage/ndb/src/mgmclient/CommandInterpreter.cpp index 72f6e7869b2..b4bbb3531ad 100644 --- a/storage/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/storage/ndb/src/mgmclient/CommandInterpreter.cpp @@ -1922,47 +1922,54 @@ CommandInterpreter::executeEventReporting(int processId, return; } BaseString tmp(parameters); - Vector<BaseString> spec; - tmp.split(spec, "="); - if(spec.size() != 2){ - ndbout << "Invalid loglevel specification: " << parameters << endl; - return; - } + Vector<BaseString> specs; + tmp.split(specs, " "); - spec[0].trim().ndb_toupper(); - int category = ndb_mgm_match_event_category(spec[0].c_str()); - if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ - if(!convert(spec[0].c_str(), category) || - category < NDB_MGM_MIN_EVENT_CATEGORY || - category > NDB_MGM_MAX_EVENT_CATEGORY){ - ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl; - return; + for (int i=0; i < specs.size(); i++) + { + Vector<BaseString> spec; + specs[i].split(spec, "="); + if(spec.size() != 2){ + ndbout << "Invalid loglevel specification: " << specs[i] << endl; + continue; } - } - int level; - if (!convert(spec[1].c_str(),level)) - { - ndbout << "Invalid level: " << spec[1].c_str() << endl; - return; - } + spec[0].trim().ndb_toupper(); + int category = ndb_mgm_match_event_category(spec[0].c_str()); + if(category == NDB_MGM_ILLEGAL_EVENT_CATEGORY){ + if(!convert(spec[0].c_str(), category) || + category < NDB_MGM_MIN_EVENT_CATEGORY || + category > NDB_MGM_MAX_EVENT_CATEGORY){ + ndbout << "Unknown category: \"" << spec[0].c_str() << "\"" << endl; + continue; + } + } - ndbout << "Executing CLUSTERLOG on node " << processId << flush; + int level; + if (!convert(spec[1].c_str(),level)) + { + ndbout << "Invalid level: " << spec[1].c_str() << endl; + continue; + } - struct ndb_mgm_reply reply; - int result; - result = ndb_mgm_set_loglevel_clusterlog(m_mgmsrv, - processId, - (ndb_mgm_event_category)category, - level, - &reply); + ndbout << "Executing CLUSTERLOG " << spec[0] << "=" << spec[1] + << " on node " << processId << flush; + + struct ndb_mgm_reply reply; + int result; + result = ndb_mgm_set_loglevel_clusterlog(m_mgmsrv, + processId, + (ndb_mgm_event_category)category, + level, + &reply); - if (result != 0) { - ndbout_c(" failed."); - printError(); - } else { - ndbout_c(" OK!"); - } + if (result != 0) { + ndbout_c(" failed."); + printError(); + } else { + ndbout_c(" OK!"); + } + } } /***************************************************************************** diff --git a/storage/ndb/src/mgmsrv/ConfigInfo.cpp b/storage/ndb/src/mgmsrv/ConfigInfo.cpp index 3df878065a7..7d4ca4bc98f 100644 --- a/storage/ndb/src/mgmsrv/ConfigInfo.cpp +++ b/storage/ndb/src/mgmsrv/ConfigInfo.cpp @@ -2148,7 +2148,17 @@ const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); /**************************************************************************** * Ctor ****************************************************************************/ -static void require(bool v) { if(!v) abort();} +static void require(bool v) +{ + if(!v) + { +#ifndef DBUG_OFF + abort(); +#else + exit(-1); +#endif + } +} ConfigInfo::ConfigInfo() : m_info(true), m_systemDefaults(true) @@ -2289,7 +2299,7 @@ ConfigInfo::ConfigInfo() ****************************************************************************/ inline void warning(const char * src, const char * arg){ ndbout << "Illegal call to ConfigInfo::" << src << "() - " << arg << endl; - abort(); + require(false); } const Properties * @@ -3429,7 +3439,7 @@ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ } case PropertiesType_Properties: default: - abort(); + ::require(false); } } return true; @@ -3441,7 +3451,7 @@ static bool saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ const Properties * sec; if(!ctx.m_currentInfo->get(ctx.fname, &sec)){ - abort(); + require(false); return false; } @@ -3512,7 +3522,7 @@ saveInConfigValues(InitConfigFileParser::Context & ctx, const char * data){ break; } default: - abort(); + require(false); } require(ok); } diff --git a/storage/ndb/src/ndbapi/ndberror.c b/storage/ndb/src/ndbapi/ndberror.c index df0e6d769c7..8a00e82398f 100644 --- a/storage/ndb/src/ndbapi/ndberror.c +++ b/storage/ndb/src/ndbapi/ndberror.c @@ -57,9 +57,6 @@ typedef struct ErrorBundle { #define OE ndberror_cl_schema_object_already_exists -static const char REDO_BUFFER_MSG[]= -"REDO log buffers overloaded, consult online manual (increase RedoBuffer, and|or decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)"; - static const char* empty_string = ""; /* @@ -168,8 +165,9 @@ ErrorBundle ErrorCodes[] = { { 830, TR, "Out of add fragment operation records" }, { 873, TR, "Out of attrinfo records for scan in tuple manager" }, { 1217, TR, "Out of operation records in local data manager (increase MaxNoOfLocalOperations)" }, - { 1220, TR, REDO_BUFFER_MSG }, + { 1220, TR, "REDO log files overloaded, consult online manual (decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)" }, { 1222, TR, "Out of transaction markers in LQH" }, + { 1224, TR, "Out of Send Buffer space in LQH" }, { 4021, TR, "Out of Send Buffer space in NDB API" }, { 4022, TR, "Out of Send Buffer space in NDB API" }, { 4032, TR, "Out of Send Buffer space in NDB API" }, @@ -200,10 +198,10 @@ ErrorBundle ErrorCodes[] = { /** * OverloadError */ - { 410, OL, REDO_BUFFER_MSG }, + { 410, OL, "REDO log files overloaded, consult online manual (decrease TimeBetweenLocalCheckpoints, and|or increase NoOfFragmentLogFiles)" }, { 677, OL, "Index UNDO buffers overloaded (increase UndoIndexBuffer)" }, { 891, OL, "Data UNDO buffers overloaded (increase UndoDataBuffer)" }, - { 1221, OL, REDO_BUFFER_MSG }, + { 1221, OL, "REDO buffers overloaded, consult online manual (increase RedoBuffer)" }, { 4006, OL, "Connect failure - out of connection objects (increase MaxNoOfConcurrentTransactions)" }, diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 4bf03938f03..84a32b52284 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -9483,7 +9483,7 @@ static void test_create_drop() rc= mysql_stmt_execute(stmt_drop); check_execute(stmt_drop, rc); if (!opt_silent) - fprintf(stdout, "droped %i\n", i); + fprintf(stdout, "dropped %i\n", i); rc= mysql_stmt_execute(stmt_create_select); check_execute(stmt_create, rc); @@ -9498,7 +9498,7 @@ static void test_create_drop() rc= mysql_stmt_execute(stmt_drop); check_execute(stmt_drop, rc); if (!opt_silent) - fprintf(stdout, "droped %i\n", i); + fprintf(stdout, "dropped %i\n", i); } mysql_stmt_close(stmt_create); diff --git a/vio/viossl.c b/vio/viossl.c index 7528e9071cf..fbbc545bb9b 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -283,9 +283,10 @@ int sslaccept(struct st_VioSSLAcceptorFd* ptr, Vio* vio, long timeout) X509* client_cert; my_bool unused; my_bool net_blocking; - enum enum_vio_type old_type; + enum enum_vio_type old_type; DBUG_ENTER("sslaccept"); - DBUG_PRINT("enter", ("sd: %d ptr: Ox%p", vio->sd,ptr)); + DBUG_PRINT("enter", ("sd: %d ptr: Ox%p, timeout: %d", + vio->sd, ptr, timeout)); old_type= vio->type; net_blocking = vio_is_blocking(vio); @@ -379,7 +380,7 @@ int sslconnect(struct st_VioSSLConnectorFd* ptr, Vio* vio, long timeout) (SSL*) vio->ssl_arg, timeout)); SSL_clear((SSL*) vio->ssl_arg); SSL_SESSION_set_timeout(SSL_get_session((SSL*) vio->ssl_arg), timeout); - SSL_set_fd ((SSL*) vio->ssl_arg, vio->sd); + SSL_set_fd ((SSL*) vio->ssl_arg, vio_ssl_fd(vio)); SSL_set_connect_state((SSL*) vio->ssl_arg); if (SSL_do_handshake((SSL*) vio->ssl_arg) < 1) { diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 44a077c33fc..766d835d2c0 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -219,9 +219,6 @@ new_VioSSLConnectorFd(const char* key_file, int result; DH *dh; DBUG_ENTER("new_VioSSLConnectorFd"); - DBUG_PRINT("enter", - ("key_file: %s, cert_file: %s, ca_path: %s, ca_file: %s, cipher: %s", - key_file, cert_file, ca_path, ca_file, cipher)); if (!(ptr=((struct st_VioSSLConnectorFd*) my_malloc(sizeof(struct st_VioSSLConnectorFd),MYF(0))))) @@ -314,9 +311,6 @@ new_VioSSLAcceptorFd(const char *key_file, int result; DH *dh; DBUG_ENTER("new_VioSSLAcceptorFd"); - DBUG_PRINT("enter", - ("key_file: %s, cert_file: %s, ca_path: %s, ca_file: %s, cipher: %s", - key_file, cert_file, ca_path, ca_file, cipher)); ptr= ((struct st_VioSSLAcceptorFd*) my_malloc(sizeof(struct st_VioSSLAcceptorFd),MYF(0))); |