BUG#11316: mysqltest, problems when assigning value with '#' to $variable

 - Add stricter checking of syntax in mysqltest
parent 9ed35f83
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
#define LAZY_GUESS_BUF_SIZE 8192 #define LAZY_GUESS_BUF_SIZE 8192
#define INIT_Q_LINES 1024 #define INIT_Q_LINES 1024
#define MIN_VAR_ALLOC 32 #define MIN_VAR_ALLOC 32
#define BLOCK_STACK_DEPTH 16 #define BLOCK_STACK_DEPTH 32
#define MAX_EXPECTED_ERRORS 10 #define MAX_EXPECTED_ERRORS 10
#define QUERY_SEND 1 #define QUERY_SEND 1
#define QUERY_REAP 2 #define QUERY_REAP 2
...@@ -136,12 +136,12 @@ static uint global_expected_errors; ...@@ -136,12 +136,12 @@ static uint global_expected_errors;
static int record = 0, opt_sleep=0; static int record = 0, opt_sleep=0;
static char *db = 0, *pass=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 int port = 0;
static my_bool opt_big_test= 0, opt_compress= 0, silent= 0, verbose = 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 my_bool tty_password= 0, ps_protocol= 0, ps_protocol_enabled= 0;
static uint start_lineno, *lineno; 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; char *manager_pass=0;
int manager_port=MYSQL_MANAGER_PORT; int manager_port=MYSQL_MANAGER_PORT;
int manager_wait_timeout=3; int manager_wait_timeout=3;
...@@ -151,11 +151,16 @@ static char **default_argv; ...@@ -151,11 +151,16 @@ static char **default_argv;
static const char *load_default_groups[]= { "mysqltest","client",0 }; static const char *load_default_groups[]= { "mysqltest","client",0 };
static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer; static char line_buffer[MAX_DELIMITER], *line_buffer_pos= line_buffer;
static char* file_name_stack[MAX_INCLUDE_DEPTH]; typedef struct
static int cur_file_name; {
static FILE* file_stack[MAX_INCLUDE_DEPTH]; FILE* file;
static FILE** cur_file; const char *file_name;
static FILE** file_stack_end; } 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 uint lineno_stack[MAX_INCLUDE_DEPTH];
static char TMPDIR[FN_REFLEN]; static char TMPDIR[FN_REFLEN];
static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER; static char delimiter[MAX_DELIMITER]= DEFAULT_DELIMITER;
...@@ -293,7 +298,7 @@ Q_COMMENT_WITH_COMMAND ...@@ -293,7 +298,7 @@ Q_COMMENT_WITH_COMMAND
/* this should really be called command */ /* this should really be called command */
struct st_query struct st_query
{ {
char *query, *query_buf,*first_argument,*end; char *query, *query_buf,*first_argument,*last_argument,*end;
int first_word_len; int first_word_len;
my_bool abort_on_error, require_file; my_bool abort_on_error, require_file;
match_err expected_errno[MAX_EXPECTED_ERRORS]; match_err expected_errno[MAX_EXPECTED_ERRORS];
...@@ -401,7 +406,7 @@ static void var_free(void* v); ...@@ -401,7 +406,7 @@ static void var_free(void* v);
int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname); int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname);
void reject_dump(const char *record_file, char *buf, int size); 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*); static void set_charset(struct st_query*);
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); my_bool ignore_not_existing);
...@@ -427,9 +432,9 @@ static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name); ...@@ -427,9 +432,9 @@ static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name);
void free_pointer_array(POINTER_ARRAY *pa); void free_pointer_array(POINTER_ARRAY *pa);
static int initialize_replace_buffer(void); static int initialize_replace_buffer(void);
static void free_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); 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; struct st_replace *glob_replace;
static char *out_buff; static char *out_buff;
...@@ -453,9 +458,9 @@ my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } ...@@ -453,9 +458,9 @@ my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; }
static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
int len); int len);
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 char c;
register int escaped = 0; register int escaped = 0;
VAR* v; VAR* v;
...@@ -512,13 +517,13 @@ static void close_cons() ...@@ -512,13 +517,13 @@ static void close_cons()
static void close_files() static void close_files()
{ {
DBUG_ENTER("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) DBUG_PRINT("info", ("file_name: %s", cur_file->file_name));
my_fclose(*cur_file,MYF(0)); if (cur_file->file && cur_file->file != stdin)
char* p= file_name_stack[cur_file_name--]= 0; my_fclose(cur_file->file, MYF(0));
if (p) my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
free(p); cur_file->file_name= 0;
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -561,17 +566,17 @@ static void free_used_memory() ...@@ -561,17 +566,17 @@ static void free_used_memory()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
static void die(const char* fmt, ...) static void die(const char *fmt, ...)
{ {
va_list args; va_list args;
DBUG_ENTER("die"); DBUG_ENTER("die");
va_start(args, fmt); va_start(args, fmt);
if (fmt) if (fmt)
{ {
fprintf(stderr, "%s: ", my_progname); fprintf(stderr, "mysqltest: ");
if (*cur_file && cur_file > (file_stack + 1) ) if (cur_file && cur_file != file_stack)
fprintf(stderr, "In included file \"%s\": ", fprintf(stderr, "In included file \"%s\": ",
file_name_stack[cur_file_name]); cur_file->file_name);
fprintf(stderr, "At line %u: ", start_lineno); fprintf(stderr, "At line %u: ", start_lineno);
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
...@@ -596,7 +601,7 @@ static void abort_not_supported_test() ...@@ -596,7 +601,7 @@ static void abort_not_supported_test()
exit(62); exit(62);
} }
static void verbose_msg(const char* fmt, ...) static void verbose_msg(const char *fmt, ...)
{ {
va_list args; va_list args;
DBUG_ENTER("verbose_msg"); DBUG_ENTER("verbose_msg");
...@@ -605,7 +610,7 @@ static void verbose_msg(const char* fmt, ...) ...@@ -605,7 +610,7 @@ static void verbose_msg(const char* fmt, ...)
va_start(args, 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); vfprintf(stderr, fmt, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(args); va_end(args);
...@@ -615,12 +620,12 @@ static void verbose_msg(const char* fmt, ...) ...@@ -615,12 +620,12 @@ static void verbose_msg(const char* fmt, ...)
void init_parser() void init_parser()
{ {
parser.current_line = parser.read_lines = 0; parser.current_line= parser.read_lines= 0;
memset(&var_reg,0, sizeof(var_reg)); 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; MY_STAT stat_info;
char *tmp, *res_ptr; char *tmp, *res_ptr;
...@@ -686,7 +691,7 @@ err: ...@@ -686,7 +691,7 @@ err:
DBUG_RETURN(res); 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) my_bool require_option)
{ {
int error = 0; int error = 0;
...@@ -714,7 +719,7 @@ static int check_result(DYNAMIC_STRING* ds, const char* fname, ...@@ -714,7 +719,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) my_bool ignore_not_existing)
{ {
int digit; int digit;
...@@ -727,7 +732,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw, ...@@ -727,7 +732,7 @@ VAR* var_get(const char* var_name, const char** var_name_end, my_bool raw,
digit = *++var_name - '0'; digit = *++var_name - '0';
if (digit < 0 || digit >= 10) if (digit < 0 || digit >= 10)
{ {
const char* save_var_name = var_name, *end; const char *save_var_name = var_name, *end;
uint length; uint length;
end = (var_name_end) ? *var_name_end : 0; end = (var_name_end) ? *var_name_end : 0;
while (my_isvar(charset_info,*var_name) && var_name != end) while (my_isvar(charset_info,*var_name) && var_name != end)
...@@ -769,7 +774,7 @@ err: ...@@ -769,7 +774,7 @@ err:
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static VAR *var_obtain(const char* name, int len) static VAR *var_obtain(const char *name, int len)
{ {
VAR* v; VAR* v;
if ((v = (VAR*)hash_search(&var_hash, name, len))) if ((v = (VAR*)hash_search(&var_hash, name, len)))
...@@ -806,8 +811,10 @@ int var_set(const char *var_name, const char *var_name_end, ...@@ -806,8 +811,10 @@ int var_set(const char *var_name, const char *var_name_end,
} }
int open_file(const char* name) int open_file(const char *name)
{ {
DBUG_ENTER("open_file");
DBUG_PRINT("enter", ("name: %s", name));
char buff[FN_REFLEN]; char buff[FN_REFLEN];
if (!test_if_hard_path(name)) if (!test_if_hard_path(name))
{ {
...@@ -816,13 +823,17 @@ int open_file(const char* name) ...@@ -816,13 +823,17 @@ int open_file(const char* name)
} }
fn_format(buff,name,"","",4); 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"); die("Source directives are nesting too deep");
if (!(*++cur_file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0)))) cur_file++;
if (!(cur_file->file = my_fopen(buff, O_RDONLY | FILE_BINARY, MYF(0))))
{
cur_file--;
die("Could not open file %s", buff); die("Could not open file %s", buff);
}
cur_file->file_name= my_strdup(buff, MYF(MY_FAE));
*++lineno=1; *++lineno=1;
file_name_stack[++cur_file_name]= strdup(buff); DBUG_RETURN(0);
return 0;
} }
...@@ -833,14 +844,15 @@ int open_file(const char* name) ...@@ -833,14 +844,15 @@ int open_file(const char* name)
int check_eol_junk(const char *eol) int check_eol_junk(const char *eol)
{ {
char *p= (char*)eol; DBUG_ENTER("check_eol_junk");
DBUG_PRINT("enter", ("eol: %s", eol));
const char *p= eol;
/* Remove all spacing chars except new line */ /* Remove all spacing chars except new line */
while (*p && my_isspace(charset_info,*p) && (*p != '\n')) while (*p && my_isspace(charset_info, *p) && (*p != '\n'))
p++; p++;
/* Check for extra delimiter */ /* Check for extra delimiter */
size_t l= strlen(delimiter); if (*p && !strncmp(p, delimiter, delimiter_length))
if (*p && strlen(p) >= l && !strncmp(p, delimiter, l) )
die("Extra delimiter \"%s\" found", delimiter); die("Extra delimiter \"%s\" found", delimiter);
/* Allow trailing # comment */ /* Allow trailing # comment */
...@@ -850,12 +862,12 @@ int check_eol_junk(const char *eol) ...@@ -850,12 +862,12 @@ int check_eol_junk(const char *eol)
die("Missing delimiter"); die("Missing delimiter");
die("End of line junk detected: \"%s\"", p); die("End of line junk detected: \"%s\"", p);
} }
return 0; DBUG_RETURN(0);
} }
/* ugly long name, but we are following the convention */ /* 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; MYSQL* mysql = &cur_con->mysql;
for (;;) for (;;)
...@@ -880,57 +892,56 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused))) ...@@ -880,57 +892,56 @@ int do_wait_for_slave_to_stop(struct st_query* q __attribute__((unused)))
break; break;
my_sleep(SLAVE_POLL_INTERVAL); my_sleep(SLAVE_POLL_INTERVAL);
} }
return check_eol_junk(q->first_argument); return 0;
} }
int do_require_manager(struct st_query* q) int do_require_manager(struct st_query *query __attribute__((unused)) )
{ {
if (!manager) if (!manager)
abort_not_supported_test(); abort_not_supported_test();
return check_eol_junk(q->first_argument); return 0;
} }
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
int do_server_start(struct st_query* q) int do_server_start(struct st_query *q)
{ {
check_eol_junk(q->first_argument); 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)
{ {
check_eol_junk(q->first_argument); 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 *p= q->first_argument;
char com_buf[256],*com_p; char com_buf[256], *com_p;
if (!manager) if (!manager)
{ {
die("Manager is not initialized, manager commands are not possible"); die("Manager is not initialized, manager commands are not possible");
} }
com_p=strmov(com_buf,op); com_p= strmov(com_buf,op);
com_p=strmov(com_p,"_exec "); com_p= strmov(com_p,"_exec ");
if (!*p) if (!*p)
die("Missing server name in server_%s",op); die("Missing server name in server_%s", op);
while (*p && !my_isspace(charset_info,*p)) while (*p && !my_isspace(charset_info, *p))
*com_p++= *p++; *com_p++= *p++;
*com_p++=' '; *com_p++= ' ';
com_p=int10_to_str(manager_wait_timeout,com_p,10); com_p= int10_to_str(manager_wait_timeout, com_p, 10);
*com_p++ = '\n'; *com_p++= '\n';
*com_p=0; *com_p= 0;
if (mysql_manager_command(manager,com_buf,(int)(com_p-com_buf))) if (mysql_manager_command(manager, com_buf, (int)(com_p-com_buf)))
die("Error in command: %s(%d)",manager->last_error,manager->last_errno); die("Error in command: %s(%d)", manager->last_error, manager->last_errno);
while (!manager->eof) 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, die("Error fetching result line: %s(%d)", manager->last_error,
manager->last_errno); manager->last_errno);
} }
return check_eol_junk(p); q->last_argument= p;
return 0;
} }
#endif #endif
...@@ -940,7 +951,7 @@ int do_server_op(struct st_query* q,const char* op) ...@@ -940,7 +951,7 @@ int do_server_op(struct st_query* q,const char* op)
SYNOPSIS SYNOPSIS
do_source() do_source()
q called command query called command
DESCRIPTION DESCRIPTION
source <file_name> source <file_name>
...@@ -949,26 +960,24 @@ int do_server_op(struct st_query* q,const char* op) ...@@ -949,26 +960,24 @@ int do_server_op(struct st_query* q,const char* op)
*/ */
int do_source(struct st_query* q) int do_source(struct st_query *query)
{ {
char* p=q->first_argument, *name; char *p= query->first_argument, *name;
if (!*p) if (!*p)
die("Missing file name in source"); die("Missing file name in source");
name = p; name= p;
while (*p && !my_isspace(charset_info,*p)) while (*p && !my_isspace(charset_info,*p))
p++; p++;
if (*p) if (*p)
{
*p++= 0; *p++= 0;
check_eol_junk(p); query->last_argument= p;
} /*
/* If this file has already been sourced, dont source it again. If this file has already been sourced, dont source it again.
It's already available in the q_lines cache */ It's already available in the q_lines cache
*/
if (parser.current_line < (parser.read_lines - 1)) if (parser.current_line < (parser.read_lines - 1))
return 0; return 0;
return open_file(name); return open_file(name);
} }
...@@ -977,7 +986,7 @@ int do_source(struct st_query* q) ...@@ -977,7 +986,7 @@ int do_source(struct st_query* q)
SYNOPSIS SYNOPSIS
do_exec() do_exec()
q called command query called command
DESCRIPTION DESCRIPTION
exec <command> exec <command>
...@@ -989,24 +998,25 @@ int do_source(struct st_query* q) ...@@ -989,24 +998,25 @@ int do_source(struct st_query* q)
*/ */
static void do_exec(struct st_query* q) static void do_exec(struct st_query *query)
{ {
int error; int error;
DYNAMIC_STRING *ds= NULL; DYNAMIC_STRING *ds= NULL;
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
char buf[1024]; char buf[1024];
FILE *res_file; FILE *res_file;
char *cmd= q->first_argument; char *cmd= query->first_argument;
DBUG_ENTER("do_exec"); DBUG_ENTER("do_exec");
while (*cmd && my_isspace(charset_info, *cmd)) while (*cmd && my_isspace(charset_info, *cmd))
cmd++; cmd++;
if (!*cmd) if (!*cmd)
die("Missing argument in exec"); die("Missing argument in exec");
query->last_argument= query->end;
DBUG_PRINT("info", ("Executing '%s'", cmd)); DBUG_PRINT("info", ("Executing '%s'", cmd));
if (!(res_file= popen(cmd, "r")) && q->abort_on_error) if (!(res_file= popen(cmd, "r")) && query->abort_on_error)
die("popen(\"%s\", \"r\") failed", cmd); die("popen(\"%s\", \"r\") failed", cmd);
if (disable_result_log) if (disable_result_log)
...@@ -1019,7 +1029,7 @@ static void do_exec(struct st_query* q) ...@@ -1019,7 +1029,7 @@ static void do_exec(struct st_query* q)
} }
else else
{ {
if (q->record_file[0]) if (query->record_file[0])
{ {
init_dynamic_string(&ds_tmp, "", 16384, 65536); init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds= &ds_tmp; ds= &ds_tmp;
...@@ -1033,20 +1043,20 @@ static void do_exec(struct st_query* q) ...@@ -1033,20 +1043,20 @@ static void do_exec(struct st_query* q)
error= pclose(res_file); error= pclose(res_file);
if (error != 0) if (error != 0)
{ {
uint i, status= WEXITSTATUS(error); uint status= WEXITSTATUS(error), i;
my_bool ok= 0; my_bool ok= 0;
if (q->abort_on_error) if (query->abort_on_error)
die("command \"%s\" failed", cmd); die("command \"%s\" failed", cmd);
DBUG_PRINT("info", DBUG_PRINT("info",
("error: %d, status: %d", error, status)); ("error: %d, status: %d", error, status));
for (i=0 ; i < q->expected_errors ; i++) for (i= 0; i < query->expected_errors; i++)
{ {
DBUG_PRINT("info", ("expected error: %d", DBUG_PRINT("info", ("expected error: %d",
q->expected_errno[i].code.errnum)); query->expected_errno[i].code.errnum));
if ((q->expected_errno[i].type == ERR_ERRNO) && if ((query->expected_errno[i].type == ERR_ERRNO) &&
(q->expected_errno[i].code.errnum == status)) (query->expected_errno[i].code.errnum == status))
{ {
ok= 1; ok= 1;
verbose_msg("command \"%s\" failed with expected error: %d", verbose_msg("command \"%s\" failed with expected error: %d",
...@@ -1057,12 +1067,12 @@ static void do_exec(struct st_query* q) ...@@ -1057,12 +1067,12 @@ static void do_exec(struct st_query* q)
die("command \"%s\" failed with wrong error: %d", die("command \"%s\" failed with wrong error: %d",
cmd, status); cmd, status);
} }
else if (q->expected_errno[0].type == ERR_ERRNO && else if (query->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0) query->expected_errno[0].code.errnum != 0)
{ {
/* Error code we wanted was != 0, i.e. not an expected success */ /* Error code we wanted was != 0, i.e. not an expected success */
die("command \"%s\" succeeded - should have failed with errno %d...", die("command \"%s\" succeeded - should have failed with errno %d...",
cmd, q->expected_errno[0].code.errnum); cmd, query->expected_errno[0].code.errnum);
} }
if (!disable_result_log) if (!disable_result_log)
...@@ -1072,14 +1082,14 @@ static void do_exec(struct st_query* q) ...@@ -1072,14 +1082,14 @@ static void do_exec(struct st_query* q)
if (record) if (record)
{ {
if (!q->record_file[0] && !result_file) if (!query->record_file[0] && !result_file)
die("Missing result file"); die("Missing result file");
if (!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) if (ds == &ds_tmp)
dynstr_free(&ds_tmp); dynstr_free(&ds_tmp);
...@@ -1087,7 +1097,7 @@ static void do_exec(struct st_query* q) ...@@ -1087,7 +1097,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)); char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p));
MYSQL_RES *res; MYSQL_RES *res;
...@@ -1150,7 +1160,7 @@ void var_copy(VAR* dest, VAR* src) ...@@ -1150,7 +1160,7 @@ void var_copy(VAR* dest, VAR* src)
memcpy(dest->str_val,src->str_val,src->str_val_len+1); memcpy(dest->str_val,src->str_val,src->str_val_len+1);
} }
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; VAR* vp;
if (*p == '$') if (*p == '$')
...@@ -1192,69 +1202,57 @@ int eval_expr(VAR* v, const char* p, const char** p_end) ...@@ -1192,69 +1202,57 @@ int eval_expr(VAR* v, const char* p, const char** p_end)
} }
/* enum enum_operator
Increase the value of a variable
SYNOPSIS
do_inc()
q called command
DESCRIPTION
inc $var_name
*/
int do_inc(struct st_query* q)
{ {
char* p=q->first_argument; DO_DEC,
VAR* v; DO_INC
if (!*p) };
die("Missing arguments to inc");
if (*p != '$')
die("First argument to inc must be a variable (start with $)");
v = var_get(p, 0, 1, 0);
v->int_val++;
v->int_dirty = 1;
while (*p && !my_isspace(charset_info,*p))
p++;
check_eol_junk(p);
return 0;
}
/* /*
Decrease the value of a variable Decrease or increase the value of a variable
SYNOPSIS SYNOPSIS
do_dec() do_modify_var()
q called command query called command
name human readable name of operator
operator operation to perform on the var
DESCRIPTION DESCRIPTION
dec $var_name 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; char *p= query->first_argument;
VAR* v; VAR* v;
if (!*p) if (!*p)
die("Missing arguments to dec"); die("Missing arguments to %s", name);
if (*p != '$') if (*p != '$')
die("First argument to dec must be a variable (start with $)"); die("First argument to %s must be a variable (start with $)", name);
v = var_get(p, 0, 1, 0); v= var_get(p, &p, 1, 0);
switch (operator){
case DO_DEC:
v->int_val--; v->int_val--;
v->int_dirty = 1; break;
while (*p && !my_isspace(charset_info,*p)) case DO_INC:
p++; v->int_val++;
check_eol_junk(p); break;
default:
die("Invalid operator to do_operator");
break;
}
v->int_dirty= 1;
query->last_argument= ++p;
return 0; 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 v;
var_init(&v, 0, 0, 0, 0); var_init(&v, 0, 0, 0, 0);
eval_expr(&v, p, 0); /* NULL terminated */ eval_expr(&v, p, 0); /* NULL terminated */
...@@ -1277,6 +1275,7 @@ int do_system(struct st_query* q) ...@@ -1277,6 +1275,7 @@ int do_system(struct st_query* q)
else else
die("Missing arguments to system, nothing to do!"); die("Missing arguments to system, nothing to do!");
var_free(&v); var_free(&v);
q->last_argument= q->end;
return 0; return 0;
} }
...@@ -1300,10 +1299,10 @@ int do_system(struct st_query* q) ...@@ -1300,10 +1299,10 @@ int do_system(struct st_query* q)
*/ */
int do_echo(struct st_query* q) int do_echo(struct st_query *q)
{ {
char* p=q->first_argument; char *p= q->first_argument;
DYNAMIC_STRING *ds= NULL; DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp; DYNAMIC_STRING ds_tmp;
VAR v; VAR v;
var_init(&v,0,0,0,0); var_init(&v,0,0,0,0);
...@@ -1311,7 +1310,7 @@ int do_echo(struct st_query* q) ...@@ -1311,7 +1310,7 @@ int do_echo(struct st_query* q)
if (q->record_file[0]) if (q->record_file[0])
{ {
init_dynamic_string(&ds_tmp, "", 256, 512); init_dynamic_string(&ds_tmp, "", 256, 512);
ds = &ds_tmp; ds= &ds_tmp;
} }
else else
ds= &ds_res; ds= &ds_res;
...@@ -1323,40 +1322,27 @@ int do_echo(struct st_query* q) ...@@ -1323,40 +1322,27 @@ int do_echo(struct st_query* q)
var_free(&v); var_free(&v);
if (ds == &ds_tmp) if (ds == &ds_tmp)
dynstr_free(&ds_tmp); dynstr_free(&ds_tmp);
q->last_argument= q->end;
return 0; return 0;
} }
int do_sync_with_master2(const char* p) int do_sync_with_master2(long offset)
{ {
MYSQL_RES* res; MYSQL_RES* res;
MYSQL_ROW row; MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql; MYSQL* mysql= &cur_con->mysql;
char query_buf[FN_REFLEN+128]; char query_buf[FN_REFLEN+128];
int offset= 0, tries= 0; int tries= 0;
int rpl_parse; int rpl_parse;
if (!master_pos.file[0]) if (!master_pos.file[0])
{ {
die("Line %u: Calling 'sync_with_master' without calling 'save_master_pos'", start_lineno); 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); mysql_disable_rpl_parse(mysql);
const char* offset_str= p;
/* Step until end of integer arg and check it */
while (*p && !my_isspace(charset_info, *p))
{
if (!my_isdigit(charset_info, *p))
die("Invalid integer argument \"%s\"", offset_str);
p++;
}
check_eol_junk(p);
if (*offset_str)
offset = atoi(offset_str);
sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file, sprintf(query_buf, "select master_pos_wait('%s', %ld)", master_pos.file,
master_pos.pos + offset); master_pos.pos + offset);
...@@ -1366,10 +1352,10 @@ wait_for_position: ...@@ -1366,10 +1352,10 @@ wait_for_position:
die("line %u: failed in %s: %d: %s", start_lineno, query_buf, die("line %u: failed in %s: %d: %s", start_lineno, query_buf,
mysql_errno(mysql), mysql_error(mysql)); 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, die("line %u: mysql_store_result() returned NULL for '%s'", start_lineno,
query_buf); 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); die("line %u: empty result in %s", start_lineno, query_buf);
if (!row[0]) if (!row[0])
{ {
...@@ -1394,9 +1380,23 @@ wait_for_position: ...@@ -1394,9 +1380,23 @@ wait_for_position:
return 0; 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;
const char *offset_end= query->end;
int error;
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() int do_save_master_pos()
...@@ -1435,7 +1435,7 @@ int do_save_master_pos() ...@@ -1435,7 +1435,7 @@ int do_save_master_pos()
SYNOPSIS SYNOPSIS
do_let() do_let()
q called command query called command
DESCRIPTION DESCRIPTION
let $<var_name>=<var_val><delimiter> let $<var_name>=<var_val><delimiter>
...@@ -1449,34 +1449,32 @@ int do_save_master_pos() ...@@ -1449,34 +1449,32 @@ int do_save_master_pos()
Program will die if error detected Program will die if error detected
*/ */
int do_let(struct st_query* q) 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; char *var_name, *var_name_end, *var_val_start;
/* Find <var_name> */ /* Find <var_name> */
if (!*p) if (!*p)
die("Missing arguments to let"); die("Missing arguments to let");
var_name = p; var_name= p;
while (*p && *p != '=' && !my_isspace(charset_info,*p)) while (*p && (*p != '=') && !my_isspace(charset_info,*p))
p++; p++;
var_name_end = p; var_name_end= p;
if (var_name+1==var_name_end) if (var_name+1 == var_name_end)
die("Missing variable name in let"); die("Missing variable name in let");
while (*p && (*p != '=' || my_isspace(charset_info,*p))) while (my_isspace(charset_info,*p))
p++;
if (*p == '=')
p++; p++;
else if (*p++ != '=')
die("Missing assignment operator in let"); die("Missing assignment operator in let");
/* Find start of <var_val> */ /* Find start of <var_val> */
while (*p && my_isspace(charset_info,*p)) while (*p && my_isspace(charset_info,*p))
p++; p++;
var_val_start = p; var_val_start= p;
query->last_argument= query->end;
/* Assign var_val to var_name */ /* Assign var_val to var_name */
return var_set(var_name, var_name_end, var_val_start, q->end); return var_set(var_name, var_name_end, var_val_start, query->end);
} }
...@@ -1495,28 +1493,25 @@ int var_set_errno(int sql_errno) ...@@ -1495,28 +1493,25 @@ int var_set_errno(int sql_errno)
} }
int do_rpl_probe(struct st_query* q) int do_rpl_probe(struct st_query *query __attribute__((unused)))
{ {
DBUG_ENTER("do_rpl_probe"); DBUG_ENTER("do_rpl_probe");
if (mysql_rpl_probe(&cur_con->mysql)) if (mysql_rpl_probe(&cur_con->mysql))
die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql)); die("Failed in mysql_rpl_probe(): '%s'", mysql_error(&cur_con->mysql));
check_eol_junk(q->first_argument);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int do_enable_rpl_parse(struct st_query* q) int do_enable_rpl_parse(struct st_query *query __attribute__((unused)))
{ {
mysql_enable_rpl_parse(&cur_con->mysql); mysql_enable_rpl_parse(&cur_con->mysql);
check_eol_junk(q->first_argument);
return 0; return 0;
} }
int do_disable_rpl_parse(struct st_query* q) int do_disable_rpl_parse(struct st_query *query __attribute__((unused)))
{ {
mysql_disable_rpl_parse(&cur_con->mysql); mysql_disable_rpl_parse(&cur_con->mysql);
check_eol_junk(q->first_argument);
return 0; return 0;
} }
...@@ -1535,57 +1530,52 @@ int do_disable_rpl_parse(struct st_query* q) ...@@ -1535,57 +1530,52 @@ int do_disable_rpl_parse(struct st_query* q)
*/ */
int do_sleep(struct st_query* q, my_bool real_sleep) int do_sleep(struct st_query *query, my_bool real_sleep)
{ {
char *p=q->first_argument; int error= 0;
while (*p && my_isspace(charset_info,*p)) char *p= query->first_argument;
char *sleep_start, *sleep_end= query->end;
double sleep_val;
while (my_isspace(charset_info, *p))
p++; p++;
if (!*p) if (!*p)
die("Missing argument to sleep"); 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) if (opt_sleep && !real_sleep)
my_sleep(opt_sleep * 1000000L); sleep_val= opt_sleep;
else
{ my_sleep((ulong) (sleep_val * 1000000L));
int err= 0; query->last_argument= sleep_end;
double val=1; return 0;
const char* val_str= p;
while (*p && !my_isspace(charset_info,*p))
{
if (!my_isdigit(charset_info, *p) && !my_ispunct(charset_info, *p))
err= 1;
p++;
}
if (!err)
val= my_strtod(val_str, &p, &err);
if (err)
die("Invalid argument to sleep \"%s\"", q->first_argument);
my_sleep((ulong) (val * 1000000L));
}
return check_eol_junk(p++);
} }
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, *name;
char* p=q->first_argument, *name;
if (!*p) if (!*p)
die("Missing file name argument"); die("Missing file name argument");
name = p; name= p;
while (*p && !my_isspace(charset_info,*p)) while (*p && !my_isspace(charset_info,*p))
p++; p++;
if (*p) if (*p)
{
*p++= 0; *p++= 0;
check_eol_junk(p); q->last_argument= p;
}
strmake(filename, name, FN_REFLEN); 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 *charset_name= q->first_argument;
char* p; char *p;
if (!charset_name || !*charset_name) if (!charset_name || !*charset_name)
die("Missing charset name in 'character_set'"); die("Missing charset name in 'character_set'");
...@@ -1594,19 +1584,16 @@ static void set_charset(struct st_query* q) ...@@ -1594,19 +1584,16 @@ static void set_charset(struct st_query* q)
while (*p && !my_isspace(charset_info,*p)) while (*p && !my_isspace(charset_info,*p))
p++; p++;
if(*p) if(*p)
{
*p++= 0; *p++= 0;
check_eol_junk(p); q->last_argument= p;
}
charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME)); charset_info= get_charset_by_csname(charset_name,MY_CS_PRIMARY,MYF(MY_WME));
if (!charset_info) if (!charset_info)
abort_not_supported_test(); 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; uint count= 0;
DBUG_ENTER("get_errcodes"); DBUG_ENTER("get_errcodes");
...@@ -1636,7 +1623,7 @@ static uint get_errcodes(match_err *to,struct st_query* q) ...@@ -1636,7 +1623,7 @@ static uint get_errcodes(match_err *to,struct st_query* q)
} }
count++; count++;
} while (*(p++) == ','); } while (*(p++) == ',');
q->last_argument= (p - 1);
to[count].type= ERR_EMPTY; /* End of data */ to[count].type= ERR_EMPTY; /* End of data */
DBUG_RETURN(count); DBUG_RETURN(count);
} }
...@@ -1650,7 +1637,7 @@ static uint get_errcodes(match_err *to,struct st_query* q) ...@@ -1650,7 +1637,7 @@ static uint get_errcodes(match_err *to,struct st_query* q)
static char *get_string(char **to_ptr, char **from_ptr, static char *get_string(char **to_ptr, char **from_ptr,
struct st_query* q) struct st_query *q)
{ {
reg1 char c,sep; reg1 char c,sep;
char *to= *to_ptr, *from= *from_ptr, *start=to; char *to= *to_ptr, *from= *from_ptr, *start=to;
...@@ -1733,7 +1720,7 @@ static char *get_string(char **to_ptr, char **from_ptr, ...@@ -1733,7 +1720,7 @@ static char *get_string(char **to_ptr, char **from_ptr,
static void get_replace(struct st_query *q) static void get_replace(struct st_query *q)
{ {
uint i; uint i;
char *from=q->first_argument; char *from= q->first_argument;
char *buff,*start; char *buff,*start;
char word_end_chars[256],*pos; char word_end_chars[256],*pos;
POINTER_ARRAY to_array,from_array; POINTER_ARRAY to_array,from_array;
...@@ -1751,7 +1738,7 @@ static void get_replace(struct st_query *q) ...@@ -1751,7 +1738,7 @@ static void get_replace(struct st_query *q)
char *to=buff; char *to=buff;
to=get_string(&buff, &from, q); to=get_string(&buff, &from, q);
if (!*from) if (!*from)
die("Wrong number of arguments to replace in %s", q->query); die("Wrong number of arguments to replace_result in '%s'", q->query);
insert_pointer_name(&from_array,to); insert_pointer_name(&from_array,to);
to=get_string(&buff, &from, q); to=get_string(&buff, &from, q);
insert_pointer_name(&to_array,to); insert_pointer_name(&to_array,to);
...@@ -1765,10 +1752,11 @@ static void get_replace(struct st_query *q) ...@@ -1765,10 +1752,11 @@ static void get_replace(struct st_query *q)
(uint) from_array.typelib.count, (uint) from_array.typelib.count,
word_end_chars)) || word_end_chars)) ||
initialize_replace_buffer()) initialize_replace_buffer())
die("Can't initialize replace from %s", q->query); die("Can't initialize replace from '%s'", q->query);
free_pointer_array(&from_array); free_pointer_array(&from_array);
free_pointer_array(&to_array); free_pointer_array(&to_array);
my_free(start, MYF(0)); my_free(start, MYF(0));
q->last_argument= q->end;
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1784,30 +1772,18 @@ void free_replace() ...@@ -1784,30 +1772,18 @@ void free_replace()
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
int select_connection(char *p)
int select_connection_name(const char *name)
{ {
char* name;
struct connection *con; struct connection *con;
DBUG_ENTER("select_connection"); DBUG_ENTER("select_connection2");
DBUG_PRINT("enter",("name: '%s'",p)); DBUG_PRINT("enter",("name: '%s'", name));
if (!*p)
die("Missing connection name in connect");
name = p;
while (*p && !my_isspace(charset_info,*p))
p++;
if (*p) for (con= cons; con < next_con; con++)
{
*p++= 0;
check_eol_junk(p);
}
for (con = cons; con < next_con; con++)
{ {
if (!strcmp(con->name, name)) if (!strcmp(con->name, name))
{ {
cur_con = con; cur_con= con;
DBUG_RETURN(0); DBUG_RETURN(0);
} }
} }
...@@ -1815,26 +1791,42 @@ int select_connection(char *p) ...@@ -1815,26 +1791,42 @@ int select_connection(char *p)
DBUG_RETURN(1); /* Never reached */ 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; struct connection *con;
DBUG_ENTER("close_connection"); DBUG_ENTER("close_connection");
DBUG_PRINT("enter",("name: '%s'",p)); DBUG_PRINT("enter",("name: '%s'",p));
if (!*p) if (!*p)
die("Missing connection name in connect"); die("Missing connection name in connect");
name = p; name= p;
while (*p && !my_isspace(charset_info,*p)) while (*p && !my_isspace(charset_info,*p))
p++; p++;
if (*p) if (*p)
{
*p++= 0; *p++= 0;
check_eol_junk(p); q->last_argument= p;
} for (con= cons; con < next_con; con++)
for (con = cons; con < next_con; con++)
{ {
if (!strcmp(con->name, name)) if (!strcmp(con->name, name))
{ {
...@@ -1864,21 +1856,21 @@ int close_connection(struct st_query* q) ...@@ -1864,21 +1856,21 @@ int close_connection(struct st_query* q)
) are delimiters/terminators ) 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"); DBUG_ENTER("safe_get_param");
while (*str && my_isspace(charset_info,*str)) while (*str && my_isspace(charset_info,*str))
str++; str++;
*arg = str; *arg= str;
for (; *str && *str != ',' && *str != ')' ; str++) for (; *str && *str != ',' && *str != ')' ; str++)
{ {
if (my_isspace(charset_info,*str)) if (my_isspace(charset_info,*str))
*str = 0; *str= 0;
} }
if (!*str) if (!*str)
die(msg); die(msg);
*str++ = 0; *str++= 0;
DBUG_RETURN(str); DBUG_RETURN(str);
} }
...@@ -1895,9 +1887,9 @@ void init_manager() ...@@ -1895,9 +1887,9 @@ void init_manager()
} }
#endif #endif
int safe_connect(MYSQL* con, const char* host, const char* user, int safe_connect(MYSQL* con, const char *host, const char *user,
const char* pass, const char *pass,
const char* db, int port, const char* sock) const char *db, int port, const char *sock)
{ {
int con_error = 1; int con_error = 1;
int i; int i;
...@@ -1915,14 +1907,14 @@ int safe_connect(MYSQL* con, const char* host, const char* user, ...@@ -1915,14 +1907,14 @@ int safe_connect(MYSQL* con, const char* host, const char* user,
} }
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; *con_db, *con_sock;
char* p=q->first_argument; char *p= q->first_argument;
char buff[FN_REFLEN]; char buff[FN_REFLEN];
int con_port; int con_port;
int free_con_sock = 0; int free_con_sock= 0;
DBUG_ENTER("do_connect"); DBUG_ENTER("do_connect");
DBUG_PRINT("enter",("connect: %s",p)); DBUG_PRINT("enter",("connect: %s",p));
...@@ -1930,41 +1922,41 @@ int do_connect(struct st_query* q) ...@@ -1930,41 +1922,41 @@ int do_connect(struct st_query* q)
if (*p != '(') if (*p != '(')
die("Syntax error in connect - expected '(' found '%c'", *p); die("Syntax error in connect - expected '(' found '%c'", *p);
p++; p++;
p = safe_get_param(p, &con_name, "missing connection name"); 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_host, "missing connection host");
p = safe_get_param(p, &con_user, "missing connection user"); 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_pass, "missing connection password");
p = safe_get_param(p, &con_db, "missing connection db"); p= safe_get_param(p, &con_db, "missing connection db");
if (!*p || *p == ';') /* Default port and sock */ if (!*p || *p == ';') /* Default port and sock */
{ {
con_port=port; con_port= port;
con_sock=(char*) unix_sock; con_sock= (char*) unix_sock;
} }
else else
{ {
VAR* var_port, *var_sock; 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 (*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); die("Unknown variable '%s'", con_port_str+1);
con_port = var_port->int_val; con_port= var_port->int_val;
} }
else else
con_port=atoi(con_port_str); con_port= atoi(con_port_str);
p = safe_get_param(p, &con_sock, "missing connection socket"); p= safe_get_param(p, &con_sock, "missing connection socket");
if (*con_sock == '$') 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); 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"); die("Out of memory");
free_con_sock = 1; free_con_sock= 1;
memcpy(con_sock, var_sock->str_val, var_sock->str_val_len); 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;
} }
} }
check_eol_junk(p); q->last_argument= p;
if (next_con == cons_end) if (next_con == cons_end)
die("Connection limit exhausted - increase MAX_CONS in mysqltest.c"); die("Connection limit exhausted - increase MAX_CONS in mysqltest.c");
...@@ -1984,33 +1976,34 @@ int do_connect(struct st_query* q) ...@@ -1984,33 +1976,34 @@ int do_connect(struct st_query* q)
if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR) if (con_sock && !free_con_sock && *con_sock && *con_sock != FN_LIBCHAR)
con_sock=fn_format(buff, con_sock, TMPDIR, "",0); con_sock=fn_format(buff, con_sock, TMPDIR, "",0);
if (!con_db[0]) if (!con_db[0])
con_db=db; con_db= db;
/* Special database to allow one to connect without a database name */ /* Special database to allow one to connect without a database name */
if (con_db && !strcmp(con_db,"*NO-ONE*")) if (con_db && !strcmp(con_db,"*NO-ONE*"))
con_db=0; con_db= 0;
if ((safe_connect(&next_con->mysql, con_host, if ((safe_connect(&next_con->mysql, con_host,
con_user, con_pass, con_user, con_pass,
con_db, con_port, con_sock ? con_sock: 0))) con_db, con_port, con_sock ? con_sock: 0)))
die("Could not open connection '%s': %s", con_name, die("Could not open connection '%s': %s", con_name,
mysql_error(&next_con->mysql)); mysql_error(&next_con->mysql));
if (!(next_con->name = my_strdup(con_name, MYF(MY_WME)))) if (!(next_con->name= my_strdup(con_name, MYF(MY_WME))))
die(NullS); die(NullS);
cur_con = next_con++; cur_con= next_con++;
if (free_con_sock) if (free_con_sock)
my_free(con_sock, MYF(MY_WME)); my_free(con_sock, MYF(MY_WME));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
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 */ /* Check if empty block stack */
if (cur_block == 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"); die("Stray '}' - end of block before beginning");
}
/* Test if inner block has been executed */ /* Test if inner block has been executed */
if (cur_block->ok && cur_block->cmd == Q_WHILE) if (cur_block->ok && cur_block->cmd == Q_WHILE)
...@@ -2025,16 +2018,16 @@ int do_done(struct st_query* q) ...@@ -2025,16 +2018,16 @@ int do_done(struct st_query* q)
cur_block--; cur_block--;
parser.current_line++; parser.current_line++;
} }
return check_eol_junk(q->first_argument); return 0;
;
} }
int do_block(enum enum_commands cmd, struct st_query* q) int do_block(enum enum_commands cmd, struct st_query *q)
{ {
char* p=q->first_argument; char *p= q->first_argument;
const char* expr_start, *expr_end; const char *expr_start, *expr_end;
VAR v; VAR v;
const char *cmd_name= (cmd == Q_WHILE ? "while" : "if");
/* Check stack overflow */ /* Check stack overflow */
if (cur_block == block_stack_end) if (cur_block == block_stack_end)
...@@ -2054,20 +2047,20 @@ int do_block(enum enum_commands cmd, struct st_query* q) ...@@ -2054,20 +2047,20 @@ int do_block(enum enum_commands cmd, struct st_query* q)
} }
/* Parse and evaluate test expression */ /* Parse and evaluate test expression */
expr_start = strchr(p, '('); expr_start= strchr(p, '(');
if (!expr_start) if (!expr_start)
die("missing '(' in while"); die("missing '(' in %s", cmd_name);
expr_end = strrchr(expr_start, ')'); expr_end= strrchr(expr_start, ')');
if (!expr_end) if (!expr_end)
die("missing ')' in while"); die("missing ')' in %s", cmd_name);
p= (char*)expr_end+1; p= (char*)expr_end+1;
while (*p && my_isspace(charset_info, *p)) while (*p && my_isspace(charset_info, *p))
p++; p++;
if (*p=='{') if (*p == '{')
die("Missing newline between while and '{'"); die("Missing newline between %s and '{'", cmd_name);
if (*p) if (*p)
die("Missing '{' after while. Found \"%s\"", p); die("Missing '{' after %s. Found \"%s\"", cmd_name, p);
var_init(&v,0,0,0,0); var_init(&v,0,0,0,0);
eval_expr(&v, ++expr_start, &expr_end); eval_expr(&v, ++expr_start, &expr_end);
...@@ -2114,7 +2107,7 @@ my_bool end_of_query(int c) ...@@ -2114,7 +2107,7 @@ my_bool end_of_query(int c)
return 0; return 0;
for (i= 1; i < delimiter_length && for (i= 1; i < delimiter_length &&
(c= my_getc(*cur_file)) == *(delimiter + i); (c= my_getc(cur_file->file)) == *(delimiter + i);
i++) i++)
tmp[i]= c; tmp[i]= c;
...@@ -2153,10 +2146,10 @@ my_bool end_of_query(int c) ...@@ -2153,10 +2146,10 @@ my_bool end_of_query(int c)
*/ */
int read_line(char* buf, int size) int read_line(char *buf, int size)
{ {
int c; int c;
char* p= buf, *buf_end= buf + size - 1; char *p= buf, *buf_end= buf + size - 1;
int no_save= 0; int no_save= 0;
enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2, enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2,
R_ESC_SLASH_Q1, R_ESC_SLASH_Q2, R_ESC_SLASH_Q1, R_ESC_SLASH_Q2,
...@@ -2167,16 +2160,14 @@ int read_line(char* buf, int size) ...@@ -2167,16 +2160,14 @@ int read_line(char* buf, int size)
for (; p < buf_end ;) for (; p < buf_end ;)
{ {
no_save= 0; no_save= 0;
c= my_getc(*cur_file); c= my_getc(cur_file->file);
if (feof(*cur_file)) if (feof(cur_file->file))
{ {
found_eof: found_eof:
if ((*cur_file) != stdin) if (cur_file->file != stdin)
my_fclose(*cur_file, MYF(0)); my_fclose(cur_file->file, MYF(0));
cur_file--; my_free((gptr)cur_file->file_name, MYF(MY_ALLOW_ZERO_PTR));
char* p= file_name_stack[cur_file_name--]= 0; cur_file->file_name= 0;
if (p)
free(p);
lineno--; lineno--;
start_lineno= *lineno; start_lineno= *lineno;
if (cur_file == file_stack) if (cur_file == file_stack)
...@@ -2191,6 +2182,7 @@ int read_line(char* buf, int size) ...@@ -2191,6 +2182,7 @@ int read_line(char* buf, int size)
} }
DBUG_RETURN(1); DBUG_RETURN(1);
} }
cur_file--;
continue; continue;
} }
...@@ -2313,9 +2305,9 @@ int read_line(char* buf, int size) ...@@ -2313,9 +2305,9 @@ int read_line(char* buf, int size)
for (i= 1; i < charlen; i++) for (i= 1; i < charlen; i++)
{ {
if (feof(*cur_file)) if (feof(cur_file->file))
goto found_eof; /* FIXME: could we just break here?! */ goto found_eof; /* FIXME: could we just break here?! */
c= my_getc(*cur_file); c= my_getc(cur_file->file);
*p++ = c; *p++ = c;
} }
if (! my_ismbchar(charset_info, mb_start, p)) if (! my_ismbchar(charset_info, mb_start, p))
...@@ -2332,13 +2324,14 @@ int read_line(char* buf, int size) ...@@ -2332,13 +2324,14 @@ int read_line(char* buf, int size)
} }
} }
*p= 0; /* Always end with \0 */ *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 Create a query from a set of lines
SYNOPSIS SYNOPSIS
read_query()
q_ptr pointer where to return the new query q_ptr pointer where to return the new query
DESCRIPTION DESCRIPTION
...@@ -2360,7 +2353,7 @@ static char read_query_buf[MAX_QUERY]; ...@@ -2360,7 +2353,7 @@ static char read_query_buf[MAX_QUERY];
int read_query(struct st_query** q_ptr) int read_query(struct st_query** q_ptr)
{ {
char *p = read_query_buf, * p1 ; char *p= read_query_buf, *p1;
struct st_query* q; struct st_query* q;
DBUG_ENTER("read_query"); DBUG_ENTER("read_query");
...@@ -2377,7 +2370,7 @@ int read_query(struct st_query** q_ptr) ...@@ -2377,7 +2370,7 @@ int read_query(struct st_query** q_ptr)
q->require_file= 0; q->require_file= 0;
q->first_word_len= 0; q->first_word_len= 0;
q->type = Q_UNKNOWN; q->type= Q_UNKNOWN;
q->query_buf= q->query= 0; q->query_buf= q->query= 0;
if (read_line(read_query_buf, sizeof(read_query_buf))) if (read_line(read_query_buf, sizeof(read_query_buf)))
{ {
...@@ -2387,7 +2380,7 @@ int read_query(struct st_query** q_ptr) ...@@ -2387,7 +2380,7 @@ int read_query(struct st_query** q_ptr)
DBUG_PRINT("info", ("query: %s", read_query_buf)); DBUG_PRINT("info", ("query: %s", read_query_buf));
if (*p == '#') if (*p == '#')
{ {
q->type = Q_COMMENT; q->type= Q_COMMENT;
/* This goto is to avoid losing the "expected error" info. */ /* This goto is to avoid losing the "expected error" info. */
goto end; goto end;
} }
...@@ -2414,10 +2407,10 @@ int read_query(struct st_query** q_ptr) ...@@ -2414,10 +2407,10 @@ int read_query(struct st_query** q_ptr)
p++; p++;
for (; my_isdigit(charset_info, *p); p++) for (; my_isdigit(charset_info, *p); p++)
expected_errno = expected_errno * 10 + *p - '0'; expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0].code.errnum = expected_errno; q->expected_errno[0].code.errnum= expected_errno;
q->expected_errno[0].type= ERR_ERRNO; q->expected_errno[0].type= ERR_ERRNO;
q->expected_errno[1].type= ERR_EMPTY; q->expected_errno[1].type= ERR_EMPTY;
q->expected_errors=1; q->expected_errors= 1;
} }
else if (*p == 'S') /* SQLSTATE */ else if (*p == 'S') /* SQLSTATE */
{ {
...@@ -2428,10 +2421,9 @@ int read_query(struct st_query** q_ptr) ...@@ -2428,10 +2421,9 @@ int read_query(struct st_query** q_ptr)
q->expected_errno[0].code.sqlstate[i]= '\0'; q->expected_errno[0].code.sqlstate[i]= '\0';
q->expected_errno[0].type= ERR_SQLSTATE; q->expected_errno[0].type= ERR_SQLSTATE;
q->expected_errno[1].type= ERR_EMPTY; q->expected_errno[1].type= ERR_EMPTY;
q->expected_errors=1; q->expected_errors= 1;
} }
} }
while (*p && my_isspace(charset_info, *p)) while (*p && my_isspace(charset_info, *p))
p++ ; p++ ;
if (*p == '@') if (*p == '@')
...@@ -2590,7 +2582,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), ...@@ -2590,7 +2582,9 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
argument= buff; argument= buff;
} }
fn_format(buff, argument, "", "", 4); 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); die("Could not open %s: errno = %d", argument, errno);
break; break;
} }
...@@ -2676,7 +2670,7 @@ int parse_args(int argc, char **argv) ...@@ -2676,7 +2670,7 @@ int parse_args(int argc, char **argv)
return 0; 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 ; int i,c ;
for (i = 0; (c = *str++) && i < size - 1; i++) for (i = 0; (c = *str++) && i < size - 1; i++)
...@@ -2685,7 +2679,7 @@ char* safe_str_append(char* buf, const char* str, int size) ...@@ -2685,7 +2679,7 @@ char* safe_str_append(char* buf, const char* str, int size)
return buf; 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; int fd;
char buff[FN_REFLEN]; char buff[FN_REFLEN];
...@@ -2704,7 +2698,7 @@ void str_to_file(const char* fname, char* str, int size) ...@@ -2704,7 +2698,7 @@ void str_to_file(const char* fname, char* str, int size)
my_close(fd, MYF(0)); 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]; char reject_file[FN_REFLEN];
str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size); str_to_file(fn_format(reject_file, record_file,"",".reject",2), buf, size);
...@@ -2879,8 +2873,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -2879,8 +2873,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
if (q->abort_on_error) if (q->abort_on_error)
die("query '%s' failed: %d: %s", query, die("query '%s' failed: %d: %s", query,
mysql_errno(mysql), mysql_error(mysql)); mysql_errno(mysql), mysql_error(mysql));
else
{
for (i=0 ; (uint) i < q->expected_errors ; i++) for (i=0 ; (uint) i < q->expected_errors ; i++)
{ {
if (((q->expected_errno[i].type == ERR_ERRNO) && if (((q->expected_errno[i].type == ERR_ERRNO) &&
...@@ -2934,13 +2927,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -2934,13 +2927,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
not fail the whole test case not fail the whole test case
*/ */
goto end; goto end;
}
/*{
verbose_msg("failed in mysql_store_result for query '%s' (%d)", query,
mysql_errno(mysql));
error = 1;
goto end;
}*/
} }
if (q->expected_errno[0].type == ERR_ERRNO && if (q->expected_errno[0].type == ERR_ERRNO &&
...@@ -2964,7 +2951,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -2964,7 +2951,7 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
if (!disable_result_log) if (!disable_result_log)
{ {
ulong affected_rows= 0; ulong affected_rows;
if (res) if (res)
{ {
...@@ -3749,7 +3736,7 @@ int main(int argc, char **argv) ...@@ -3749,7 +3736,7 @@ int main(int argc, char **argv)
struct st_query *q; struct st_query *q;
my_bool require_file=0, q_send_flag=0; my_bool require_file=0, q_send_flag=0;
char save_file[FN_REFLEN]; char save_file[FN_REFLEN];
MY_INIT("mysqltest"); MY_INIT(argv[0]);
{ {
DBUG_ENTER("main"); DBUG_ENTER("main");
DBUG_PROCESS(argv[0]); DBUG_PROCESS(argv[0]);
...@@ -3765,10 +3752,9 @@ int main(int argc, char **argv) ...@@ -3765,10 +3752,9 @@ int main(int argc, char **argv)
cur_con = cons; cur_con = cons;
memset(file_stack, 0, sizeof(file_stack)); memset(file_stack, 0, sizeof(file_stack));
memset(file_name_stack, 0, sizeof(file_name_stack));
memset(&master_pos, 0, sizeof(master_pos)); memset(&master_pos, 0, sizeof(master_pos));
file_stack_end = file_stack + MAX_INCLUDE_DEPTH - 1; file_stack_end= file_stack + MAX_INCLUDE_DEPTH - 1;
cur_file = file_stack; cur_file= file_stack;
lineno = lineno_stack; lineno = lineno_stack;
my_init_dynamic_array(&q_lines, sizeof(struct st_query*), INIT_Q_LINES, my_init_dynamic_array(&q_lines, sizeof(struct st_query*), INIT_Q_LINES,
INIT_Q_LINES); INIT_Q_LINES);
...@@ -3787,8 +3773,9 @@ int main(int argc, char **argv) ...@@ -3787,8 +3773,9 @@ int main(int argc, char **argv)
die("Can't initialize MySQL server"); die("Can't initialize MySQL server");
if (cur_file == file_stack) if (cur_file == file_stack)
{ {
*++cur_file= stdin; DBUG_ASSERT(cur_file->file == 0);
++cur_file_name; cur_file->file= stdin;
cur_file->file_name= my_strdup("<stdin>", MYF(MY_WME));
} }
*lineno=1; *lineno=1;
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
...@@ -3835,40 +3822,29 @@ int main(int argc, char **argv) ...@@ -3835,40 +3822,29 @@ int main(int argc, char **argv)
get_query_type(q); get_query_type(q);
if (cur_block->ok) if (cur_block->ok)
{ {
q->last_argument= q->first_argument;
processed = 1; processed = 1;
switch (q->type) { switch (q->type) {
case Q_CONNECT: do_connect(q); break; case Q_CONNECT: 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_DISCONNECT:
case Q_DIRTY_CLOSE: case Q_DIRTY_CLOSE:
close_connection(q); break; close_connection(q); break;
case Q_RPL_PROBE: do_rpl_probe(q); break; case Q_RPL_PROBE: do_rpl_probe(q); break;
case Q_ENABLE_RPL_PARSE: do_enable_rpl_parse(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_DISABLE_RPL_PARSE: do_disable_rpl_parse(q); break;
case Q_ENABLE_QUERY_LOG: case Q_ENABLE_QUERY_LOG: disable_query_log=0; break;
disable_query_log=0; check_eol_junk(q->first_argument); break; case Q_DISABLE_QUERY_LOG: disable_query_log=1; break;
case Q_DISABLE_QUERY_LOG: case Q_ENABLE_ABORT_ON_ERROR: abort_on_error=1; break;
disable_query_log=1; check_eol_junk(q->first_argument); break; case Q_DISABLE_ABORT_ON_ERROR: abort_on_error=0; break;
case Q_ENABLE_ABORT_ON_ERROR: case Q_ENABLE_RESULT_LOG: disable_result_log=0; break;
abort_on_error=1; check_eol_junk(q->first_argument); break; case Q_DISABLE_RESULT_LOG: disable_result_log=1; break;
case Q_DISABLE_ABORT_ON_ERROR: case Q_ENABLE_WARNINGS: disable_warnings=0; break;
abort_on_error=0; check_eol_junk(q->first_argument); break; case Q_DISABLE_WARNINGS: disable_warnings=1; break;
case Q_ENABLE_RESULT_LOG: case Q_ENABLE_INFO: disable_info=0; break;
disable_result_log=0; check_eol_junk(q->first_argument); break; case Q_DISABLE_INFO: disable_info=1; break;
case Q_DISABLE_RESULT_LOG: case Q_ENABLE_METADATA: display_metadata=1; break;
disable_result_log=1; check_eol_junk(q->first_argument); break; case Q_DISABLE_METADATA: display_metadata=0; break;
case Q_ENABLE_WARNINGS:
disable_warnings=0; check_eol_junk(q->first_argument); break;
case Q_DISABLE_WARNINGS:
disable_warnings=1; check_eol_junk(q->first_argument); break;
case Q_ENABLE_INFO:
disable_info=0; check_eol_junk(q->first_argument); break;
case Q_DISABLE_INFO:
disable_info=1; check_eol_junk(q->first_argument); break;
case Q_ENABLE_METADATA:
display_metadata=1; check_eol_junk(q->first_argument); break;
case Q_DISABLE_METADATA:
display_metadata=0; check_eol_junk(q->first_argument); break;
case Q_SOURCE: do_source(q); break; case Q_SOURCE: do_source(q); break;
case Q_SLEEP: do_sleep(q, 0); break; case Q_SLEEP: do_sleep(q, 0); break;
case Q_REAL_SLEEP: do_sleep(q, 1); break; case Q_REAL_SLEEP: do_sleep(q, 1); break;
...@@ -3878,26 +3854,24 @@ int main(int argc, char **argv) ...@@ -3878,26 +3854,24 @@ int main(int argc, char **argv)
case Q_SERVER_START: do_server_start(q); break; case Q_SERVER_START: do_server_start(q); break;
case Q_SERVER_STOP: do_server_stop(q); break; case Q_SERVER_STOP: do_server_stop(q); break;
#endif #endif
case Q_INC: do_inc(q); break; case Q_INC: do_modify_var(q, "inc", DO_INC); break;
case Q_DEC: do_dec(q); break; case Q_DEC: do_modify_var(q, "dec", DO_DEC); break;
case Q_ECHO: do_echo(q); break; case Q_ECHO: do_echo(q); break;
case Q_SYSTEM: do_system(q); break; case Q_SYSTEM: do_system(q); break;
case Q_DELIMITER: case Q_DELIMITER:
strmake(delimiter, q->first_argument, sizeof(delimiter) - 1); strmake(delimiter, q->first_argument, sizeof(delimiter) - 1);
delimiter_length= strlen(delimiter); delimiter_length= strlen(delimiter);
check_eol_junk(q->first_argument+delimiter_length); q->last_argument= q->first_argument+delimiter_length;
break; break;
case Q_DISPLAY_VERTICAL_RESULTS: case Q_DISPLAY_VERTICAL_RESULTS:
display_result_vertically= TRUE; display_result_vertically= TRUE;
check_eol_junk(q->first_argument);
break; break;
case Q_DISPLAY_HORIZONTAL_RESULTS: case Q_DISPLAY_HORIZONTAL_RESULTS:
display_result_vertically= FALSE; display_result_vertically= FALSE;
check_eol_junk(q->first_argument);
break; break;
case Q_LET: do_let(q); break; case Q_LET: do_let(q); break;
case Q_EVAL_RESULT: case Q_EVAL_RESULT:
eval_result = 1; check_eol_junk(q->first_argument); break; eval_result = 1; break;
case Q_EVAL: case Q_EVAL:
if (q->query == q->query_buf) if (q->query == q->query_buf)
{ {
...@@ -3930,6 +3904,7 @@ int main(int argc, char **argv) ...@@ -3930,6 +3904,7 @@ int main(int argc, char **argv)
} }
error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND); error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND);
display_result_vertically= old_display_result_vertically; display_result_vertically= old_display_result_vertically;
q->last_argument= q->end;
break; break;
} }
case Q_QUERY: case Q_QUERY:
...@@ -3954,6 +3929,7 @@ int main(int argc, char **argv) ...@@ -3954,6 +3929,7 @@ int main(int argc, char **argv)
save_file[0]=0; save_file[0]=0;
} }
error |= run_query(&cur_con->mysql, q, flags); error |= run_query(&cur_con->mysql, q, flags);
q->last_argument= q->end;
break; break;
} }
case Q_SEND: case Q_SEND:
...@@ -3973,6 +3949,7 @@ int main(int argc, char **argv) ...@@ -3973,6 +3949,7 @@ int main(int argc, char **argv)
is given on this connection. is given on this connection.
*/ */
error |= run_query(&cur_con->mysql, q, QUERY_SEND); error |= run_query(&cur_con->mysql, q, QUERY_SEND);
q->last_argument= q->end;
break; break;
case Q_RESULT: case Q_RESULT:
get_file_name(save_file,q); get_file_name(save_file,q);
...@@ -3997,21 +3974,18 @@ int main(int argc, char **argv) ...@@ -3997,21 +3974,18 @@ int main(int argc, char **argv)
{ {
do_save_master_pos(); do_save_master_pos();
if (*q->first_argument) if (*q->first_argument)
select_connection(q->first_argument); select_connection(q);
else else
{ select_connection_name("slave");
char buf[] = "slave"; do_sync_with_master2(0);
select_connection(buf);
}
do_sync_with_master2("");
break; break;
} }
case Q_COMMENT: /* Ignore row */ case Q_COMMENT: /* Ignore row */
case Q_COMMENT_WITH_COMMAND: case Q_COMMENT_WITH_COMMAND:
q->last_argument= q->end;
break; break;
case Q_PING: case Q_PING:
(void) mysql_ping(&cur_con->mysql); (void) mysql_ping(&cur_con->mysql);
check_eol_junk(q->first_argument);
break; break;
case Q_EXEC: case Q_EXEC:
do_exec(q); do_exec(q);
...@@ -4019,32 +3993,26 @@ int main(int argc, char **argv) ...@@ -4019,32 +3993,26 @@ int main(int argc, char **argv)
case Q_START_TIMER: case Q_START_TIMER:
/* Overwrite possible earlier start of timer */ /* Overwrite possible earlier start of timer */
timer_start= timer_now(); timer_start= timer_now();
check_eol_junk(q->first_argument);
break; break;
case Q_END_TIMER: case Q_END_TIMER:
/* End timer before ending mysqltest */ /* End timer before ending mysqltest */
timer_output(); timer_output();
got_end_timer= TRUE; got_end_timer= TRUE;
check_eol_junk(q->first_argument);
break; break;
case Q_CHARACTER_SET: case Q_CHARACTER_SET:
set_charset(q); set_charset(q);
break; break;
case Q_DISABLE_PS_PROTOCOL: case Q_DISABLE_PS_PROTOCOL:
ps_protocol_enabled= 0; ps_protocol_enabled= 0;
check_eol_junk(q->first_argument);
break; break;
case Q_ENABLE_PS_PROTOCOL: case Q_ENABLE_PS_PROTOCOL:
ps_protocol_enabled= ps_protocol; ps_protocol_enabled= ps_protocol;
check_eol_junk(q->first_argument);
break; break;
case Q_DISABLE_RECONNECT: case Q_DISABLE_RECONNECT:
cur_con->mysql.reconnect= 0; cur_con->mysql.reconnect= 0;
check_eol_junk(q->first_argument);
break; break;
case Q_ENABLE_RECONNECT: case Q_ENABLE_RECONNECT:
cur_con->mysql.reconnect= 1; cur_con->mysql.reconnect= 1;
check_eol_junk(q->first_argument);
break; break;
default: processed = 0; break; default: processed = 0; break;
...@@ -4061,6 +4029,8 @@ int main(int argc, char **argv) ...@@ -4061,6 +4029,8 @@ int main(int argc, char **argv)
default: current_line_inc = 1; break; default: current_line_inc = 1; break;
} }
} }
else
check_eol_junk(q->last_argument);
parser.current_line += current_line_inc; parser.current_line += current_line_inc;
} }
...@@ -4936,15 +4906,16 @@ static void get_replace_column(struct st_query *q) ...@@ -4936,15 +4906,16 @@ static void get_replace_column(struct st_query *q)
to= get_string(&buff, &from, q); to= get_string(&buff, &from, q);
if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS) if (!(column_number= atoi(to)) || column_number > MAX_COLUMNS)
die("Wrong column number to replace_columns in %s", q->query); die("Wrong column number to replace_column in '%s'", q->query);
if (!*from) if (!*from)
die("Wrong number of arguments to replace in %s", q->query); die("Wrong number of arguments to replace_column in '%s'", q->query);
to= get_string(&buff, &from, q); to= get_string(&buff, &from, q);
my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR); my_free(replace_column[column_number-1], MY_ALLOW_ZERO_PTR);
replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE)); replace_column[column_number-1]= my_strdup(to, MYF(MY_WME | MY_FAE));
set_if_bigger(max_replace_column, column_number); set_if_bigger(max_replace_column, column_number);
} }
my_free(start, MYF(0)); my_free(start, MYF(0));
q->last_argument= q->end;
} }
#if defined(__NETWARE__) || defined(__WIN__) #if defined(__NETWARE__) || defined(__WIN__)
......
...@@ -308,13 +308,41 @@ test2 ...@@ -308,13 +308,41 @@ test2
test3 test3
test4 test4
1 1
mysqltest: In included file "./include/mysqltest_while.inc": At line 32: Nesting too deeply 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 ')' in while mysqltest: At line 1: missing ')' in while
mysqltest: At line 1: Missing '{' after while. Found "dec $i" 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 of block before beginning
mysqltest: At line 1: Stray '}' - end of block before beginning mysqltest: At line 1: Stray 'end' command - end of block before beginning
mysqltest: At line 1: query '' failed: 1065: Query was empty mysqltest: At line 1: query '' failed: 1065: Query was empty
mysqltest: At line 1: Missing '{' after while. Found "echo hej" mysqltest: At line 1: Missing '{' after while. Found "echo hej"
mysqltest: At line 3: Missing end of block mysqltest: At line 3: Missing end of block
mysqltest: At line 1: Missing newline between while and '{' 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"
...@@ -238,7 +238,7 @@ drop table t1; ...@@ -238,7 +238,7 @@ drop table t1;
create table `t1 `(a int); create table `t1 `(a int);
--error 1102 --error 1102
create database `db1 `; create database `db1 `;
--error 1166; --error 1166
create table t1(`a ` int); create table t1(`a ` int);
# #
......
...@@ -11,19 +11,19 @@ drop table if exists t1, t2; ...@@ -11,19 +11,19 @@ drop table if exists t1, t2;
--enable_warnings --enable_warnings
CREATE TABLE t1 ( a int ); CREATE TABLE t1 ( a int );
INSERT INTO t1 VALUES (1),(2),(1); INSERT INTO t1 VALUES (1),(2),(1);
--error 1062; --error 1062
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
--error 1146; --error 1146
select * from t2; select * from t2;
--error 1062; --error 1062
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1; CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=INNODB SELECT a FROM t1;
--error 1146; --error 1146
select * from t2; select * from t2;
--error 1062; --error 1062
CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; CREATE TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
--error 1146; --error 1146
select * from t2; select * from t2;
--error 1062; --error 1062
CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1; CREATE TEMPORARY TABLE t2 ( PRIMARY KEY (a) ) ENGINE=MYISAM SELECT a FROM t1;
--error 1146; --error 1146
select * from t2; select * from t2;
...@@ -6,13 +6,13 @@ drop database if exists mysqltest; ...@@ -6,13 +6,13 @@ drop database if exists mysqltest;
drop database if exists client_test_db; drop database if exists client_test_db;
--enable_warnings --enable_warnings
--error 1051; --error 1051
drop table t1; drop table t1;
create table t1(n int); create table t1(n int);
insert into t1 values(1); insert into t1 values(1);
create temporary table t1( n int); create temporary table t1( n int);
insert into t1 values(2); insert into t1 values(2);
--error 1050; --error 1050
create table t1(n int); create table t1(n int);
drop table t1; drop table t1;
select * from t1; select * from t1;
...@@ -56,13 +56,13 @@ drop database mysqltest; ...@@ -56,13 +56,13 @@ drop database mysqltest;
# test drop/create database and FLUSH TABLES WITH READ LOCK # test drop/create database and FLUSH TABLES WITH READ LOCK
flush tables with read lock; flush tables with read lock;
--error 1209,1223; --error 1209,1223
create database mysqltest; create database mysqltest;
unlock tables; unlock tables;
create database mysqltest; create database mysqltest;
show databases; show databases;
flush tables with read lock; flush tables with read lock;
--error 1208,1223; --error 1208,1223
drop database mysqltest; drop database mysqltest;
unlock tables; unlock tables;
drop database mysqltest; drop database mysqltest;
...@@ -73,7 +73,7 @@ drop database mysqltest; ...@@ -73,7 +73,7 @@ drop database mysqltest;
# test create table and FLUSH TABLES WITH READ LOCK # test create table and FLUSH TABLES WITH READ LOCK
drop table t1; drop table t1;
flush tables with read lock; flush tables with read lock;
--error 1223; --error 1223
create table t1(n int); create table t1(n int);
unlock tables; unlock tables;
create table t1(n int); create table t1(n int);
......
...@@ -37,7 +37,7 @@ connection con1; ...@@ -37,7 +37,7 @@ connection con1;
select * from t1; select * from t1;
connection con2; connection con2;
flush tables with read lock; flush tables with read lock;
--error 1099; --error 1099
drop table t2; drop table t2;
connection con1; connection con1;
send drop table t2; send drop table t2;
......
...@@ -300,7 +300,7 @@ handler t5 open as h5; ...@@ -300,7 +300,7 @@ handler t5 open as h5;
handler h5 read first limit 9; handler h5 read first limit 9;
# close first # close first
alter table t1 engine=MyISAM; alter table t1 engine=MyISAM;
--error 1109; --error 1109
handler h1 read first limit 9; handler h1 read first limit 9;
handler h2 read first limit 9; handler h2 read first limit 9;
handler h3 read first limit 9; handler h3 read first limit 9;
...@@ -308,22 +308,22 @@ handler h4 read first limit 9; ...@@ -308,22 +308,22 @@ handler h4 read first limit 9;
handler h5 read first limit 9; handler h5 read first limit 9;
# close last # close last
alter table t5 engine=MyISAM; alter table t5 engine=MyISAM;
--error 1109; --error 1109
handler h1 read first limit 9; handler h1 read first limit 9;
handler h2 read first limit 9; handler h2 read first limit 9;
handler h3 read first limit 9; handler h3 read first limit 9;
handler h4 read first limit 9; handler h4 read first limit 9;
--error 1109; --error 1109
handler h5 read first limit 9; handler h5 read first limit 9;
# close middle # close middle
alter table t3 engine=MyISAM; alter table t3 engine=MyISAM;
--error 1109; --error 1109
handler h1 read first limit 9; handler h1 read first limit 9;
handler h2 read first limit 9; handler h2 read first limit 9;
--error 1109; --error 1109
handler h3 read first limit 9; handler h3 read first limit 9;
handler h4 read first limit 9; handler h4 read first limit 9;
--error 1109; --error 1109
handler h5 read first limit 9; handler h5 read first limit 9;
handler h2 close; handler h2 close;
handler h4 close; handler h4 close;
...@@ -335,11 +335,11 @@ handler h1_1 read first limit 9; ...@@ -335,11 +335,11 @@ handler h1_1 read first limit 9;
handler h1_2 read first limit 9; handler h1_2 read first limit 9;
handler h1_3 read first limit 9; handler h1_3 read first limit 9;
alter table t1 engine=MyISAM; alter table t1 engine=MyISAM;
--error 1109; --error 1109
handler h1_1 read first limit 9; handler h1_1 read first limit 9;
--error 1109; --error 1109
handler h1_2 read first limit 9; handler h1_2 read first limit 9;
--error 1109; --error 1109
handler h1_3 read first limit 9; handler h1_3 read first limit 9;
drop table t1; drop table t1;
drop table t2; drop table t2;
......
...@@ -1183,7 +1183,7 @@ drop table t1; ...@@ -1183,7 +1183,7 @@ drop table t1;
# #
CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB; CREATE TABLE t1 ( a char(10) ) ENGINE=InnoDB;
--error 1214; --error 1214
SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE); SELECT a FROM t1 WHERE MATCH (a) AGAINST ('test' IN BOOLEAN MODE);
DROP TABLE t1; DROP TABLE t1;
......
...@@ -705,6 +705,69 @@ while ($i) ...@@ -705,6 +705,69 @@ while ($i)
--error 1 --error 1
--exec echo -e "while (0){\n echo hej;" | $MYSQL_TEST 2>&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 # TODO Test queries, especially their errormessages... so it's easy to debug
# new scripts and diagnose errors # new scripts and diagnose errors
......
...@@ -89,7 +89,7 @@ kill @id; ...@@ -89,7 +89,7 @@ kill @id;
# We don't drop t3 as this is a temporary table # We don't drop t3 as this is a temporary table
drop table t2; drop table t2;
connection master; connection master;
--error 1053; --error 1053
reap; reap;
connection slave; connection slave;
# The SQL slave thread should now have stopped because the query was killed on # The SQL slave thread should now have stopped because the query was killed on
......
...@@ -22,7 +22,7 @@ set sql_log_bin=0; ...@@ -22,7 +22,7 @@ set sql_log_bin=0;
insert into t1 values(2); insert into t1 values(2);
set sql_log_bin=1; set sql_log_bin=1;
save_master_pos; save_master_pos;
--error 1062; --error 1062
insert into t1 values(1),(2); insert into t1 values(1),(2);
drop table t1; drop table t1;
save_master_pos; save_master_pos;
......
...@@ -5,7 +5,7 @@ source include/master-slave.inc; ...@@ -5,7 +5,7 @@ source include/master-slave.inc;
drop table if exists t1, t2; drop table if exists t1, t2;
--enable_warnings --enable_warnings
create table t1 (a int); create table t1 (a int);
--error 1051; --error 1051
drop table t1, t2; drop table t1, t2;
save_master_pos; save_master_pos;
connection slave; connection slave;
......
...@@ -6,7 +6,7 @@ source include/master-slave.inc; ...@@ -6,7 +6,7 @@ source include/master-slave.inc;
connection master; connection master;
create table t1 (a int primary key); create table t1 (a int primary key);
# generate an error that goes to the binlog # generate an error that goes to the binlog
--error 1062; --error 1062
insert into t1 values (1),(1); insert into t1 values (1),(1);
save_master_pos; save_master_pos;
connection slave; connection slave;
...@@ -45,7 +45,7 @@ select (@id := id) - id from t3; ...@@ -45,7 +45,7 @@ select (@id := id) - id from t3;
kill @id; kill @id;
drop table t2,t3; drop table t2,t3;
connection master; connection master;
--error 0,1053; --error 0,1053
reap; reap;
connection master1; connection master1;
show binlog events from 79; show binlog events from 79;
......
...@@ -123,7 +123,7 @@ connection master; ...@@ -123,7 +123,7 @@ connection master;
reset master; reset master;
create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60), create table t2 (day date,id int(9),category enum('a','b','c'),name varchar(60),
unique(day)); unique(day));
--error 1062; --error 1062
load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields load data infile '../../std_data/rpl_loaddata2.dat' into table t2 fields
terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by terminated by ',' optionally enclosed by '%' escaped by '@' lines terminated by
'\n##\n' starting by '>' ignore 1 lines; '\n##\n' starting by '>' ignore 1 lines;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment