Commit 3b88de9a authored by unknown's avatar unknown

Merge bk-internal.mysql.com:/home/bk/mysql-5.0

into  neptunus.(none):/home/msvensson/mysql/wl2930/my50-wl2930-integration
parents 15f4fafb 4b5e9206
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
**********************************************************************/ **********************************************************************/
#define MTEST_VERSION "2.5" #define MTEST_VERSION "2.6"
#include <my_global.h> #include <my_global.h>
#include <mysql_embed.h> #include <mysql_embed.h>
...@@ -108,7 +108,8 @@ ...@@ -108,7 +108,8 @@
enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD, enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC, OPT_MANAGER_PORT,OPT_MANAGER_WAIT_TIMEOUT, OPT_SKIP_SAFEMALLOC,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH, OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER,OPT_PS_PROTOCOL}; OPT_SSL_CIPHER,OPT_PS_PROTOCOL,OPT_SP_PROTOCOL,OPT_CURSOR_PROTOCOL,
OPT_VIEW_PROTOCOL};
/* ************************************************************************ */ /* ************************************************************************ */
/* /*
...@@ -158,7 +159,11 @@ static char *db = 0, *pass=0; ...@@ -158,7 +159,11 @@ 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;
static my_bool ps_protocol= 0, ps_protocol_enabled= 0;
static my_bool sp_protocol= 0, sp_protocol_enabled= 0;
static my_bool view_protocol= 0, view_protocol_enabled= 0;
static my_bool cursor_protocol= 0, cursor_protocol_enabled= 0;
static int parsing_disabled= 0; static int parsing_disabled= 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;
...@@ -212,11 +217,14 @@ static int got_end_timer= FALSE; ...@@ -212,11 +217,14 @@ static int got_end_timer= FALSE;
static void timer_output(void); static void timer_output(void);
static ulonglong timer_now(void); static ulonglong timer_now(void);
static my_regex_t ps_re; /* Holds precompiled re for valid PS statements */ /* Precompiled re's */
static void ps_init_re(void); static my_regex_t ps_re; /* the query can be run using PS protocol */
static int ps_match_re(char *); static my_regex_t sp_re; /* the query can be run as a SP */
static char *ps_eprint(int); static my_regex_t view_re; /* the query can be run as a view*/
static void ps_free_reg(void);
static void init_re(void);
static int match_re(my_regex_t *, char *);
static void free_re(void);
static const char *embedded_server_groups[]= static const char *embedded_server_groups[]=
{ {
...@@ -239,7 +247,10 @@ typedef struct ...@@ -239,7 +247,10 @@ typedef struct
struct connection struct connection
{ {
MYSQL mysql; MYSQL mysql;
/* Used when creating views and sp, to avoid implicit commit */
MYSQL* util_mysql;
char *name; char *name;
MYSQL_STMT* stmt;
}; };
typedef struct typedef struct
...@@ -247,8 +258,6 @@ typedef struct ...@@ -247,8 +258,6 @@ typedef struct
int read_lines,current_line; int read_lines,current_line;
} PARSER; } PARSER;
MYSQL_RES *last_result=0;
PARSER parser; PARSER parser;
MASTER_POS master_pos; MASTER_POS master_pos;
/* if set, all results are concated and compared against this file */ /* if set, all results are concated and compared against this file */
...@@ -435,8 +444,7 @@ static VAR* var_init(VAR* v, const char *name, int name_len, const char *val, ...@@ -435,8 +444,7 @@ static VAR* var_init(VAR* v, const char *name, int name_len, const char *val,
static void var_free(void* v); static void var_free(void* v);
int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname); void dump_result_to_reject_file(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*); int close_connection(struct st_query*);
static void set_charset(struct st_query*); static void set_charset(struct st_query*);
...@@ -463,9 +471,8 @@ void free_replace(); ...@@ -463,9 +471,8 @@ void free_replace();
static int insert_pointer_name(reg1 POINTER_ARRAY *pa,my_string name); 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 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); static 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;
...@@ -490,10 +497,10 @@ my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } ...@@ -490,10 +497,10 @@ 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 replace_dynstr_append(DYNAMIC_STRING *ds, const char *val); static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val);
static int handle_error(const char *query, struct st_query *q, static void handle_error(const char *query, struct st_query *q,
unsigned int err_errno, const char *err_error, unsigned int err_errno, const char *err_error,
const char *err_sqlstate, DYNAMIC_STRING *ds); const char *err_sqlstate, DYNAMIC_STRING *ds);
static int handle_no_error(struct st_query *q); static void 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)
{ {
...@@ -540,11 +547,14 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query) ...@@ -540,11 +547,14 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query)
static void close_cons() static void close_cons()
{ {
DBUG_ENTER("close_cons"); DBUG_ENTER("close_cons");
if (last_result)
mysql_free_result(last_result);
for (--next_con; next_con >= cons; --next_con) for (--next_con; next_con >= cons; --next_con)
{ {
if (next_con->stmt)
mysql_stmt_close(next_con->stmt);
next_con->stmt= 0;
mysql_close(&next_con->mysql); mysql_close(&next_con->mysql);
if (next_con->util_mysql)
mysql_close(next_con->util_mysql);
my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR));
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -598,8 +608,7 @@ static void free_used_memory() ...@@ -598,8 +608,7 @@ static void free_used_memory()
my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); my_free(pass,MYF(MY_ALLOW_ZERO_PTR));
free_defaults(default_argv); free_defaults(default_argv);
mysql_server_end(); mysql_server_end();
if (ps_protocol) free_re();
ps_free_reg();
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -623,6 +632,10 @@ static void die(const char *fmt, ...) ...@@ -623,6 +632,10 @@ static void die(const char *fmt, ...)
va_end(args); va_end(args);
free_used_memory(); free_used_memory();
my_end(MY_CHECK_ERROR); my_end(MY_CHECK_ERROR);
if (!silent)
printf("not ok\n");
exit(1); exit(1);
} }
...@@ -665,7 +678,7 @@ void init_parser() ...@@ -665,7 +678,7 @@ void init_parser()
} }
int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) static 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;
...@@ -733,7 +746,21 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) ...@@ -733,7 +746,21 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname)
DBUG_RETURN(res); DBUG_RETURN(res);
} }
static int check_result(DYNAMIC_STRING* ds, const char *fname, /*
Check the content of ds against content of file fname
SYNOPSIS
check_result
ds - content to be checked
fname - name of file to check against
require_option - if set and check fails, the test will be aborted with the special
exit code "not supported test"
RETURN VALUES
error - the function will not return
*/
static void check_result(DYNAMIC_STRING* ds, const char *fname,
my_bool require_option) my_bool require_option)
{ {
int res= dyn_string_cmp(ds, fname); int res= dyn_string_cmp(ds, fname);
...@@ -745,17 +772,18 @@ static int check_result(DYNAMIC_STRING* ds, const char *fname, ...@@ -745,17 +772,18 @@ static int check_result(DYNAMIC_STRING* ds, const char *fname,
case RESULT_OK: case RESULT_OK:
break; /* ok */ break; /* ok */
case RESULT_LENGTH_MISMATCH: case RESULT_LENGTH_MISMATCH:
verbose_msg("Result length mismatch"); dump_result_to_reject_file(fname, ds->str, ds->length);
die("Result length mismatch");
break; break;
case RESULT_CONTENT_MISMATCH: case RESULT_CONTENT_MISMATCH:
verbose_msg("Result content mismatch"); dump_result_to_reject_file(fname, ds->str, ds->length);
die("Result content mismatch");
break; break;
default: /* impossible */ default: /* impossible */
die("Unknown error code from dyn_string_cmp()"); die("Unknown error code from dyn_string_cmp()");
} }
if (res != RESULT_OK)
reject_dump(fname, ds->str, ds->length); DBUG_VOID_RETURN;
DBUG_RETURN(res);
} }
...@@ -1042,7 +1070,6 @@ static void do_exec(struct st_query *query) ...@@ -1042,7 +1070,6 @@ static void do_exec(struct st_query *query)
{ {
int error; int error;
DYNAMIC_STRING *ds= NULL; DYNAMIC_STRING *ds= NULL;
DYNAMIC_STRING ds_tmp;
char buf[1024]; char buf[1024];
FILE *res_file; FILE *res_file;
char *cmd= query->first_argument; char *cmd= query->first_argument;
...@@ -1069,14 +1096,7 @@ static void do_exec(struct st_query *query) ...@@ -1069,14 +1096,7 @@ static void do_exec(struct st_query *query)
} }
else else
{ {
if (query->record_file[0])
{
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds= &ds_tmp;
}
else
ds= &ds_res; ds= &ds_res;
while (fgets(buf, sizeof(buf), res_file)) while (fgets(buf, sizeof(buf), res_file))
replace_dynstr_append(ds, buf); replace_dynstr_append(ds, buf);
} }
...@@ -1117,47 +1137,54 @@ static void do_exec(struct st_query *query) ...@@ -1117,47 +1137,54 @@ static void do_exec(struct st_query *query)
cmd, query->expected_errno[0].code.errnum); cmd, query->expected_errno[0].code.errnum);
} }
if (!disable_result_log)
{
if (glob_replace)
free_replace(); free_replace();
DBUG_VOID_RETURN;
if (record)
{
if (!query->record_file[0] && !result_file)
die("Missing result file");
if (!result_file)
str_to_file(query->record_file, ds->str, ds->length);
}
else if (query->record_file[0])
{
error= check_result(ds, query->record_file, query->require_file);
}
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
}
} }
/*
Set variable from the result of a query
SYNOPSIS
var_query_set()
var variable to set from query
query start of query string to execute
query_end end of the query string to execute
DESCRIPTION
let @<var_name> = `<query>`
Execute the query and assign the first row of result to var as
a tab separated strings
Also assign each column of the result set to
variable "$<var_name>_<column_name>"
Thus the tab separated output can be read from $<var_name> and
and each individual column can be read as $<var_name>_<col_name>
*/
int var_query_set(VAR* v, const char *p, const char** p_end) int var_query_set(VAR* var, const char *query, const char** query_end)
{ {
char* end = (char*)((p_end && *p_end) ? *p_end : p + strlen(p)); char* end = (char*)((query_end && *query_end) ?
*query_end : query + strlen(query));
MYSQL_RES *res; MYSQL_RES *res;
MYSQL_ROW row; MYSQL_ROW row;
MYSQL* mysql = &cur_con->mysql; MYSQL* mysql = &cur_con->mysql;
LINT_INIT(res); LINT_INIT(res);
while (end > p && *end != '`') while (end > query && *end != '`')
--end; --end;
if (p == end) if (query == end)
die("Syntax error in query, missing '`'"); die("Syntax error in query, missing '`'");
++p; ++query;
if (mysql_real_query(mysql, p, (int)(end - p)) || if (mysql_real_query(mysql, query, (int)(end - query)) ||
!(res = mysql_store_result(mysql))) !(res = mysql_store_result(mysql)))
{ {
*end = 0; *end = 0;
die("Error running query '%s': %s", p, mysql_error(mysql)); die("Error running query '%s': %d: %s", query,
mysql_errno(mysql) ,mysql_error(mysql));
} }
if ((row = mysql_fetch_row(res)) && row[0]) if ((row = mysql_fetch_row(res)) && row[0])
...@@ -1170,21 +1197,39 @@ int var_query_set(VAR* v, const char *p, const char** p_end) ...@@ -1170,21 +1197,39 @@ int var_query_set(VAR* v, const char *p, const char** p_end)
uint i; uint i;
ulong *lengths; ulong *lengths;
char *end; char *end;
MYSQL_FIELD *fields= mysql_fetch_fields(res);
init_dynamic_string(&result, "", 16384, 65536); init_dynamic_string(&result, "", 16384, 65536);
lengths= mysql_fetch_lengths(res); lengths= mysql_fetch_lengths(res);
for (i=0; i < mysql_num_fields(res); i++) for (i=0; i < mysql_num_fields(res); i++)
{ {
if (row[0]) if (row[0])
{
/* Add to <var_name>_<col_name> */
uint j;
char var_col_name[MAX_VAR_NAME];
uint length= snprintf(var_col_name, MAX_VAR_NAME,
"$%s_%s", var->name, fields[i].name);
/* Convert characters not allowed in variable names to '_' */
for (j= 1; j < length; j++)
{
if (!my_isvar(charset_info,var_col_name[j]))
var_col_name[j]= '_';
}
var_set(var_col_name, var_col_name + length,
row[i], row[i] + lengths[i]);
/* Add column to tab separated string */
dynstr_append_mem(&result, row[i], lengths[i]); dynstr_append_mem(&result, row[i], lengths[i]);
}
dynstr_append_mem(&result, "\t", 1); dynstr_append_mem(&result, "\t", 1);
} }
end= result.str + result.length-1; end= result.str + result.length-1;
eval_expr(v, result.str, (const char**) &end); eval_expr(var, result.str, (const char**) &end);
dynstr_free(&result); dynstr_free(&result);
} }
else else
eval_expr(v, "", 0); eval_expr(var, "", 0);
mysql_free_result(res); mysql_free_result(res);
return 0; return 0;
...@@ -1302,10 +1347,13 @@ int do_modify_var(struct st_query *query, const char *name, ...@@ -1302,10 +1347,13 @@ int do_modify_var(struct st_query *query, const char *name,
int do_system(struct st_query *q) int do_system(struct st_query *q)
{ {
DYNAMIC_STRING *ds;
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 */
ds= &ds_res;
if (v.str_val_len) if (v.str_val_len)
{ {
char expr_buf[1024]; char expr_buf[1024];
...@@ -1318,8 +1366,11 @@ int do_system(struct st_query *q) ...@@ -1318,8 +1366,11 @@ int do_system(struct st_query *q)
{ {
if (q->abort_on_error) if (q->abort_on_error)
die("system command '%s' failed", expr_buf); die("system command '%s' failed", expr_buf);
/* If ! abort_on_error, display message and continue */
verbose_msg("system command '%s' failed", expr_buf); /* If ! abort_on_error, log message and continue */
dynstr_append(ds, "system command '");
replace_dynstr_append(ds, expr_buf);
dynstr_append(ds, "' failed\n");
} }
} }
else else
...@@ -1353,16 +1404,9 @@ int do_echo(struct st_query *q) ...@@ -1353,16 +1404,9 @@ int do_echo(struct st_query *q)
{ {
char *p= q->first_argument; char *p= q->first_argument;
DYNAMIC_STRING *ds; DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp;
VAR v; VAR v;
var_init(&v,0,0,0,0); var_init(&v,0,0,0,0);
if (q->record_file[0])
{
init_dynamic_string(&ds_tmp, "", 256, 512);
ds= &ds_tmp;
}
else
ds= &ds_res; ds= &ds_res;
eval_expr(&v, p, 0); /* NULL terminated */ eval_expr(&v, p, 0); /* NULL terminated */
...@@ -1370,8 +1414,6 @@ int do_echo(struct st_query *q) ...@@ -1370,8 +1414,6 @@ int do_echo(struct st_query *q)
dynstr_append_mem(ds, v.str_val, v.str_val_len); dynstr_append_mem(ds, v.str_val, v.str_val_len);
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
var_free(&v); var_free(&v);
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
q->last_argument= q->end; q->last_argument= q->end;
return 0; return 0;
} }
...@@ -1400,7 +1442,7 @@ int do_sync_with_master2(long offset) ...@@ -1400,7 +1442,7 @@ int do_sync_with_master2(long offset)
die("failed in %s: %d: %s", query_buf, mysql_errno(mysql), die("failed in %s: %d: %s", query_buf, mysql_errno(mysql),
mysql_error(mysql)); mysql_error(mysql));
if (!(last_result= res= mysql_store_result(mysql))) if (!(res= mysql_store_result(mysql)))
die("mysql_store_result() returned NULL for '%s'", query_buf); die("mysql_store_result() returned NULL for '%s'", query_buf);
if (!(row= mysql_fetch_row(res))) if (!(row= mysql_fetch_row(res)))
die("empty result in %s", query_buf); die("empty result in %s", query_buf);
...@@ -1417,7 +1459,6 @@ int do_sync_with_master2(long offset) ...@@ -1417,7 +1459,6 @@ int do_sync_with_master2(long offset)
goto wait_for_position; goto wait_for_position;
} }
mysql_free_result(res); mysql_free_result(res);
last_result=0;
if (rpl_parse) if (rpl_parse)
mysql_enable_rpl_parse(mysql); mysql_enable_rpl_parse(mysql);
...@@ -1456,13 +1497,13 @@ int do_save_master_pos() ...@@ -1456,13 +1497,13 @@ int do_save_master_pos()
die("failed in show master status: %d: %s", die("failed in show master status: %d: %s",
mysql_errno(mysql), mysql_error(mysql)); mysql_errno(mysql), mysql_error(mysql));
if (!(last_result =res = mysql_store_result(mysql))) if (!(res = mysql_store_result(mysql)))
die("mysql_store_result() retuned NULL for '%s'", query); die("mysql_store_result() retuned NULL for '%s'", query);
if (!(row = mysql_fetch_row(res))) if (!(row = mysql_fetch_row(res)))
die("empty result in show master status"); die("empty result in show master status");
strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1);
master_pos.pos = strtoul(row[1], (char**) 0, 10); master_pos.pos = strtoul(row[1], (char**) 0, 10);
mysql_free_result(res); last_result=0; mysql_free_result(res);
if (rpl_parse) if (rpl_parse)
mysql_enable_rpl_parse(mysql); mysql_enable_rpl_parse(mysql);
...@@ -1594,6 +1635,7 @@ int do_sleep(struct st_query *query, my_bool real_sleep) ...@@ -1594,6 +1635,7 @@ int do_sleep(struct st_query *query, my_bool real_sleep)
if (opt_sleep && !real_sleep) if (opt_sleep && !real_sleep)
sleep_val= opt_sleep; sleep_val= opt_sleep;
DBUG_PRINT("info", ("sleep_val: %f", sleep_val));
my_sleep((ulong) (sleep_val * 1000000L)); my_sleep((ulong) (sleep_val * 1000000L));
query->last_argument= sleep_end; query->last_argument= sleep_end;
return 0; return 0;
...@@ -1831,7 +1873,7 @@ void free_replace() ...@@ -1831,7 +1873,7 @@ void free_replace()
{ {
my_free((char*) glob_replace,MYF(0)); my_free((char*) glob_replace,MYF(0));
glob_replace=0; glob_replace=0;
free_replace_buffer(); my_free(out_buff,MYF(MY_WME));
} }
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -1910,6 +1952,9 @@ int close_connection(struct st_query *q) ...@@ -1910,6 +1952,9 @@ int close_connection(struct st_query *q)
} }
#endif #endif
mysql_close(&con->mysql); mysql_close(&con->mysql);
if (con->util_mysql)
mysql_close(con->util_mysql);
con->util_mysql= 0;
my_free(con->name, MYF(0)); my_free(con->name, MYF(0));
/* /*
When the connection is closed set name to "closed_connection" When the connection is closed set name to "closed_connection"
...@@ -2002,16 +2047,15 @@ void init_manager() ...@@ -2002,16 +2047,15 @@ void init_manager()
0 - success, non-0 - failure 0 - success, non-0 - failure
*/ */
int safe_connect(MYSQL* con, const char *host, const char *user, int safe_connect(MYSQL* mysql, 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;
my_bool reconnect= 1; my_bool reconnect= 1;
int i; int i;
for (i= 0; i < MAX_CON_TRIES; ++i) for (i= 0; i < MAX_CON_TRIES; ++i)
{ {
if (mysql_real_connect(con, host,user, pass, db, port, sock, if (mysql_real_connect(mysql, host,user, pass, db, port, sock,
CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
{ {
con_error= 0; con_error= 0;
...@@ -2023,7 +2067,7 @@ int safe_connect(MYSQL* con, const char *host, const char *user, ...@@ -2023,7 +2067,7 @@ int safe_connect(MYSQL* con, const char *host, const char *user,
TODO: change this to 0 in future versions, but the 'kill' test relies on TODO: change this to 0 in future versions, but the 'kill' test relies on
existing behavior existing behavior
*/ */
mysql_options(con, MYSQL_OPT_RECONNECT, (char *)&reconnect); mysql_options(mysql, MYSQL_OPT_RECONNECT, (char *)&reconnect);
return con_error; return con_error;
} }
...@@ -2056,20 +2100,10 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, ...@@ -2056,20 +2100,10 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host,
const char* db, int port, const char* sock, const char* db, int port, const char* sock,
int* create_conn) int* create_conn)
{ {
DYNAMIC_STRING ds_tmp, *ds; DYNAMIC_STRING *ds;
my_bool reconnect= 1; my_bool reconnect= 1;
int error= 0; int error= 0;
/*
Altough we ignore --require or --result before connect() command we still
need to handle record_file because of "@result_file sql-command" syntax.
*/
if (q->record_file[0])
{
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds= &ds_tmp;
}
else
ds= &ds_res; ds= &ds_res;
if (!disable_query_log) if (!disable_query_log)
...@@ -2103,13 +2137,15 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, ...@@ -2103,13 +2137,15 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host,
if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0, if (!mysql_real_connect(con, host, user, pass, db, port, sock ? sock: 0,
CLIENT_MULTI_STATEMENTS)) CLIENT_MULTI_STATEMENTS))
{ {
error= handle_error("connect", q, mysql_errno(con), mysql_error(con), handle_error("connect", q, mysql_errno(con), mysql_error(con),
mysql_sqlstate(con), ds); mysql_sqlstate(con), ds);
*create_conn= 0; *create_conn= 0;
goto err; goto err;
} }
else if (handle_no_error(q)) else
{ {
handle_no_error(q);
/* /*
Fail if there was no error but we expected it. Fail if there was no error but we expected it.
We also don't want to have connection in this case. We also don't want to have connection in this case.
...@@ -2126,20 +2162,8 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, ...@@ -2126,20 +2162,8 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host,
*/ */
mysql_options(con, MYSQL_OPT_RECONNECT, (char *)&reconnect); mysql_options(con, MYSQL_OPT_RECONNECT, (char *)&reconnect);
if (record)
{
if (!q->record_file[0] && !result_file)
die("Missing result file");
if (!result_file)
str_to_file(q->record_file, ds->str, ds->length);
}
else if (q->record_file[0])
error|= check_result(ds, q->record_file, q->require_file);
err: err:
free_replace(); free_replace();
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
return error; return error;
} }
...@@ -2269,7 +2293,7 @@ int do_connect(struct st_query *q) ...@@ -2269,7 +2293,7 @@ int do_connect(struct st_query *q)
if (!mysql_init(&next_con->mysql)) if (!mysql_init(&next_con->mysql))
die("Failed on mysql_init()"); die("Failed on mysql_init()");
if (opt_compress || con_compress) if (opt_compress || con_compress)
mysql_options(&next_con->mysql,MYSQL_OPT_COMPRESS,NullS); mysql_options(&next_con->mysql, MYSQL_OPT_COMPRESS, NullS);
mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(&next_con->mysql, MYSQL_OPT_LOCAL_INFILE, 0);
mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name); mysql_options(&next_con->mysql, MYSQL_SET_CHARSET_NAME, charset_name);
...@@ -2287,10 +2311,10 @@ int do_connect(struct st_query *q) ...@@ -2287,10 +2311,10 @@ int do_connect(struct st_query *q)
con_db= 0; con_db= 0;
if (q->abort_on_error) if (q->abort_on_error)
{ {
if ((safe_connect(&next_con->mysql, con_host, con_user, con_pass, if (safe_connect(&next_con->mysql, con_host, 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': %d %s", con_name,
mysql_error(&next_con->mysql)); mysql_errno(&next_con->mysql), mysql_error(&next_con->mysql));
} }
else else
error= connect_n_handle_errors(q, &next_con->mysql, con_host, con_user, error= connect_n_handle_errors(q, &next_con->mysql, con_host, con_user,
...@@ -2653,7 +2677,7 @@ static char read_query_buf[MAX_QUERY]; ...@@ -2653,7 +2677,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;
struct st_query* q; struct st_query* q;
DBUG_ENTER("read_query"); DBUG_ENTER("read_query");
...@@ -2672,10 +2696,13 @@ int read_query(struct st_query** q_ptr) ...@@ -2672,10 +2696,13 @@ int read_query(struct st_query** q_ptr)
q->type= Q_UNKNOWN; q->type= Q_UNKNOWN;
q->query_buf= q->query= 0; q->query_buf= q->query= 0;
read_query_buf[0]= 0;
if (read_line(read_query_buf, sizeof(read_query_buf))) if (read_line(read_query_buf, sizeof(read_query_buf)))
{ {
check_eol_junk(read_query_buf);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
DBUG_PRINT("info", ("query: %s", read_query_buf)); DBUG_PRINT("info", ("query: %s", read_query_buf));
if (*p == '#') if (*p == '#')
{ {
...@@ -2700,20 +2727,12 @@ int read_query(struct st_query** q_ptr) ...@@ -2700,20 +2727,12 @@ int read_query(struct st_query** q_ptr)
{ {
while (*p && my_isspace(charset_info, *p)) while (*p && my_isspace(charset_info, *p))
p++ ; p++ ;
if (*p == '@')
{
p++;
p1 = q->record_file;
while (!my_isspace(charset_info, *p) &&
p1 < q->record_file + sizeof(q->record_file) - 1)
*p1++ = *p++;
*p1 = 0;
}
} }
end: end:
while (*p && my_isspace(charset_info, *p)) while (*p && my_isspace(charset_info, *p))
p++; p++;
if (!(q->query_buf= q->query= my_strdup(p, MYF(MY_WME)))) if (!(q->query_buf= q->query= my_strdup(p, MYF(MY_WME))))
die(NullS); die(NullS);
...@@ -2772,6 +2791,15 @@ static struct my_option my_long_options[] = ...@@ -2772,6 +2791,15 @@ static struct my_option my_long_options[] =
{"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication", {"ps-protocol", OPT_PS_PROTOCOL, "Use prepared statements protocol for communication",
(gptr*) &ps_protocol, (gptr*) &ps_protocol, 0, (gptr*) &ps_protocol, (gptr*) &ps_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"sp-protocol", OPT_SP_PROTOCOL, "Use stored procedures for select",
(gptr*) &sp_protocol, (gptr*) &sp_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"cursor-protocol", OPT_CURSOR_PROTOCOL, "Use cursors for prepared statment",
(gptr*) &cursor_protocol, (gptr*) &cursor_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"view-protocol", OPT_VIEW_PROTOCOL, "Use views for select",
(gptr*) &view_protocol, (gptr*) &view_protocol, 0,
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"quiet", 's', "Suppress all normal output.", (gptr*) &silent, {"quiet", 's', "Suppress all normal output.", (gptr*) &silent,
(gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, (gptr*) &silent, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"record", 'r', "Record output of test_file into result file.", {"record", 'r', "Record output of test_file into result file.",
...@@ -2833,8 +2861,6 @@ void usage() ...@@ -2833,8 +2861,6 @@ void usage()
#include <help_end.h> #include <help_end.h>
#include <help_end.h>
static my_bool static my_bool
get_one_option(int optid, const struct my_option *opt __attribute__((unused)), get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
...@@ -2952,27 +2978,29 @@ int parse_args(int argc, char **argv) ...@@ -2952,27 +2978,29 @@ int parse_args(int argc, char **argv)
return 0; return 0;
} }
char* safe_str_append(char *buf, const char *str, int size)
{
int i,c ;
for (i = 0; (c = *str++) && i < size - 1; i++)
*buf++ = c;
*buf = 0;
return buf;
}
void str_to_file(const char *fname, char *str, int size) /*
Write the content of str into file
SYNOPSIS
str_to_file
fname - name of file to truncate/create and write to
str - content to write to file
size - size of content witten to file
*/
static void str_to_file(const char *fname, char *str, int size)
{ {
int fd; int fd;
char buff[FN_REFLEN]; char buff[FN_REFLEN];
if (!test_if_hard_path(fname)) if (!test_if_hard_path(fname))
{ {
strxmov(buff, opt_basedir, fname, NullS); strxmov(buff, opt_basedir, fname, NullS);
fname=buff; fname= buff;
} }
fn_format(buff,fname,"","",4); fn_format(buff,fname,"","",4);
if ((fd = my_open(buff, O_WRONLY | O_CREAT | O_TRUNC, if ((fd= my_open(buff, O_WRONLY | O_CREAT | O_TRUNC,
MYF(MY_WME | MY_FFNF))) < 0) MYF(MY_WME | MY_FFNF))) < 0)
die("Could not open %s: errno = %d", buff, errno); die("Could not open %s: errno = %d", buff, errno);
if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP))) if (my_write(fd, (byte*)str, size, MYF(MY_WME|MY_FNABP)))
...@@ -2980,7 +3008,8 @@ void str_to_file(const char *fname, char *str, int size) ...@@ -2980,7 +3008,8 @@ 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 dump_result_to_reject_file(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);
...@@ -3002,6 +3031,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val, ...@@ -3002,6 +3031,7 @@ static void replace_dynstr_append_mem(DYNAMIC_STRING *ds, const char *val,
dynstr_append_mem(ds, val, len); dynstr_append_mem(ds, val, len);
} }
/* Append zero-terminated string to ds, with optional replace */ /* Append zero-terminated string to ds, with optional replace */
static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val) static void replace_dynstr_append(DYNAMIC_STRING *ds, const char *val)
...@@ -3020,7 +3050,7 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) ...@@ -3020,7 +3050,7 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
MYSQL_ROW row; MYSQL_ROW row;
uint num_fields= mysql_num_fields(res); uint num_fields= mysql_num_fields(res);
MYSQL_FIELD *fields= !display_result_vertically ? 0 : mysql_fetch_fields(res); MYSQL_FIELD *fields= !display_result_vertically ? 0 : mysql_fetch_fields(res);
unsigned long *lengths; ulong *lengths;
while ((row = mysql_fetch_row(res))) while ((row = mysql_fetch_row(res)))
{ {
uint i; uint i;
...@@ -3062,231 +3092,401 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) ...@@ -3062,231 +3092,401 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res)
/* /*
* flags control the phased/stages of query execution to be performed Append all results from ps execution to the dynamic string separated
* if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on with '\t'. Values may be converted with 'replace_column'
* the result will be read - for regular query, both bits must be on
*/ */
static int run_query_normal(MYSQL *mysql, struct st_query *q, int flags); static void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
static int run_query_stmt (MYSQL *mysql, struct st_query *q, int flags); MYSQL_FIELD *field, uint num_fields)
static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds);
static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields,
DYNAMIC_STRING *ds);
static int run_query(MYSQL *mysql, struct st_query *q, int flags)
{ {
MYSQL_BIND *bind;
my_bool *is_null;
ulong *length;
ulonglong num_rows;
uint col_idx, row_idx;
/* /* Allocate array with bind structs, lengths and NULL flags */
Try to find out if we can run this statement using the prepared bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND),
statement protocol. MYF(MY_WME | MY_FAE | MY_ZEROFILL));
length= (ulong*) my_malloc(num_fields * sizeof(ulong),
We don't have a mysql_stmt_send_execute() so we only handle MYF(MY_WME | MY_FAE));
complete SEND+REAP. is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool),
MYF(MY_WME | MY_FAE));
If it is a '?' in the query it may be a SQL level prepared
statement already and we can't do it twice
*/
if (ps_protocol_enabled && disable_info &&
(flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query))
return run_query_stmt(mysql, q, flags);
return run_query_normal(mysql, q, flags);
}
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* Allocate data for output */
uint max_length= field[col_idx].max_length + 1;
char *str_data= (char *) my_malloc(max_length, MYF(MY_WME | MY_FAE));
static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) bind[col_idx].buffer_type= MYSQL_TYPE_STRING;
{ bind[col_idx].buffer= (char *)str_data;
MYSQL_RES* res= 0; bind[col_idx].buffer_length= max_length;
uint i; bind[col_idx].is_null= &is_null[col_idx];
int error= 0, err= 0, counter= 0; bind[col_idx].length= &length[col_idx];
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query;
char* query;
int query_len, got_error_on_send= 0;
DBUG_ENTER("run_query_normal");
DBUG_PRINT("enter",("flags: %d", flags));
if (q->type != Q_EVAL) DBUG_PRINT("bind", ("col[%d]: buffer_type: %d, buffer_length: %d",
{ col_idx,
query = q->query; bind[col_idx].buffer_type,
query_len = strlen(query); bind[col_idx].buffer_length));
}
else
{
init_dynamic_string(&eval_query, "", 16384, 65536);
do_eval(&eval_query, q->query);
query = eval_query.str;
query_len = eval_query.length;
} }
DBUG_PRINT("enter", ("query: '%-.60s'", query));
if (q->record_file[0]) /* Fill in the data into the structures created above */
{ if (mysql_stmt_bind_result(stmt, bind))
init_dynamic_string(&ds_tmp, "", 16384, 65536); die("mysql_stmt_bind_result failed: %d: %s",
ds = &ds_tmp; mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
}
else
ds= &ds_res;
if (flags & QUERY_SEND) /* Read result from each row */
num_rows= mysql_stmt_num_rows(stmt);
for (row_idx= 0; row_idx < num_rows; row_idx++)
{ {
got_error_on_send= mysql_send_query(mysql, query, query_len); if (mysql_stmt_fetch(stmt))
if (got_error_on_send && q->expected_errno[0].type == ERR_EMPTY) die("mysql_stmt_fetch failed: %d %s",
die("unable to send query '%s' (mysql_errno=%d , errno=%d)", mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
query, mysql_errno(mysql), errno);
}
do /* Read result from each column */
for (col_idx= 0; col_idx < num_fields; col_idx++)
{ {
if ((flags & QUERY_SEND) && !disable_query_log && !counter) const char *val;
ulonglong len;
if (col_idx < max_replace_column && replace_column[col_idx])
{ {
replace_dynstr_append_mem(ds,query, query_len); val= replace_column[col_idx];
dynstr_append_mem(ds, delimiter, delimiter_length); len= strlen(val);
dynstr_append_mem(ds, "\n", 1);
} }
if (!(flags & QUERY_REAP)) else if (*bind[col_idx].is_null)
DBUG_RETURN(0);
if (got_error_on_send ||
(!counter && (*mysql->methods->read_query_result)(mysql)) ||
(!(last_result= res= mysql_store_result(mysql)) &&
mysql_field_count(mysql)))
{ {
if (handle_error(query, q, mysql_errno(mysql), mysql_error(mysql), val= "NULL";
mysql_sqlstate(mysql), ds)) len= 4;
error= 1;
goto end;
} }
else
if (!disable_result_log)
{
ulong affected_rows; /* Ok to be undef if 'disable_info' is set */
LINT_INIT(affected_rows);
if (res)
{ {
MYSQL_FIELD *field= mysql_fetch_fields(res); val= (const char *) bind[col_idx].buffer;
uint num_fields= mysql_num_fields(res); len= *bind[col_idx].length;
}
if (display_metadata)
run_query_display_metadata(field, num_fields, ds);
if (!display_result_vertically) if (!display_result_vertically)
{ {
for (i = 0; i < num_fields; i++) if (col_idx) /* No tab before first col */
{
if (i)
dynstr_append_mem(ds, "\t", 1); dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append(ds, field[i].name); replace_dynstr_append_mem(ds, val, (int)len);
}
dynstr_append_mem(ds, "\n", 1);
}
append_result(ds, res);
} }
/*
Need to call mysql_affected_rows() before the new
query to find the warnings
*/
if (!disable_info)
affected_rows= (ulong)mysql_affected_rows(mysql);
/*
Add all warnings to the result. We can't do this if we are in
the middle of processing results from multi-statement, because
this will break protocol.
*/
if (!disable_warnings && !mysql_more_results(mysql) &&
mysql_warning_count(mysql))
{
MYSQL_RES *warn_res=0;
uint count= mysql_warning_count(mysql);
if (!mysql_real_query(mysql, "SHOW WARNINGS", 13))
warn_res= mysql_store_result(mysql);
if (!warn_res)
die("Warning count is %u but didn't get any warnings", count);
else else
{ {
dynstr_append_mem(ds, "Warnings:\n", 10); dynstr_append(ds, field[col_idx].name);
append_result(ds, warn_res); dynstr_append_mem(ds, "\t", 1);
mysql_free_result(warn_res); replace_dynstr_append_mem(ds, val, (int)len);
}
}
if (!disable_info)
{
char buf[40];
sprintf(buf,"affected rows: %lu\n", affected_rows);
dynstr_append(ds, buf);
if (mysql_info(mysql))
{
dynstr_append(ds, "info: ");
dynstr_append(ds, mysql_info(mysql));
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
} }
} }
if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1);
} }
if (record) if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
{ die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
if (!q->record_file[0] && !result_file) mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
die("Missing result file");
if (!result_file)
str_to_file(q->record_file, ds->str, ds->length);
}
else if (q->record_file[0])
{
error= check_result(ds, q->record_file, q->require_file);
}
if (res)
mysql_free_result(res);
last_result= 0;
counter++;
} while (!(err= mysql_next_result(mysql)));
if (err > 0)
{
/* We got an error from mysql_next_result, maybe expected */
if (handle_error(query, q, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds))
error= 1;
goto end;
}
/* If we come here the query is both executed and read successfully */ free_replace_column();
if (handle_no_error(q))
for (col_idx= 0; col_idx < num_fields; col_idx++)
{ {
error= 1; /* Free data for output */
goto end; my_free((gptr)bind[col_idx].buffer, MYF(MY_WME | MY_FAE));
} }
/* Free array with bind structs, lengths and NULL flags */
end: my_free((gptr)bind , MYF(MY_WME | MY_FAE));
free_replace(); my_free((gptr)length , MYF(MY_WME | MY_FAE));
last_result=0; my_free((gptr)is_null , MYF(MY_WME | MY_FAE));
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
if (q->type == Q_EVAL)
dynstr_free(&eval_query);
/*
We save the return code (mysql_errno(mysql)) from the last call sent
to the server into the mysqltest builtin variable $mysql_errno. This
variable then can be used from the test case itself.
*/
var_set_errno(mysql_errno(mysql));
DBUG_RETURN(error);
} }
/* /*
Handle errors which occurred after execution Append metadata for fields to output
*/
SYNOPSIS static void append_metadata(DYNAMIC_STRING *ds,
handle_error() MYSQL_FIELD *field,
query - query string uint num_fields)
q - query context {
err_errno - error number MYSQL_FIELD *field_end;
err_error - error message dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
err_sqlstate - sql state "Column_alias\tType\tLength\tMax length\tIs_null\t"
"Flags\tDecimals\tCharsetnr\n");
for (field_end= field+num_fields ;
field < field_end ;
field++)
{
char buff[22];
dynstr_append_mem(ds, field->catalog,
field->catalog_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->db, field->db_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_table,
field->org_table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->table,
field->table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_name,
field->org_name_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->name, field->name_length);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->type, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
longlong10_to_str((unsigned int) field->length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
longlong10_to_str((unsigned int) field->max_length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
"N" : "Y"), 1);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->flags, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->decimals, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->charsetnr, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\n", 1);
}
}
/*
Append affected row count and other info to output
*/
static void append_info(DYNAMIC_STRING *ds, ulonglong affected_rows,
const char *info)
{
char buf[40];
sprintf(buf,"affected rows: %llu\n", affected_rows);
dynstr_append(ds, buf);
if (info)
{
dynstr_append(ds, "info: ");
dynstr_append(ds, info);
dynstr_append_mem(ds, "\n", 1);
}
}
/*
Display the table headings with the names tab separated
*/
static void append_table_headings(DYNAMIC_STRING *ds,
MYSQL_FIELD *field,
uint num_fields)
{
uint col_idx;
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
if (col_idx)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append(ds, field[col_idx].name);
}
dynstr_append_mem(ds, "\n", 1);
}
/*
Fetch warnings from server and append to ds
RETURN VALUE
Number of warnings appended to ds
*/
static int append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
{
uint count;
MYSQL_RES *warn_res;
DBUG_ENTER("append_warnings");
if (!(count= mysql_warning_count(mysql)))
DBUG_RETURN(0);
/*
If one day we will support execution of multi-statements
through PS API we should not issue SHOW WARNINGS until
we have not read all results...
*/
DBUG_ASSERT(!mysql_more_results(mysql));
if (mysql_real_query(mysql, "SHOW WARNINGS", 13))
die("Error running query \"SHOW WARNINGS\": %s", mysql_error(mysql));
if (!(warn_res= mysql_store_result(mysql)))
die("Warning count is %u but didn't get any warnings",
count);
append_result(ds, warn_res);
mysql_free_result(warn_res);
DBUG_PRINT("warnings", ("%s", ds->str));
DBUG_RETURN(count);
}
/*
Run query using MySQL C API
SYNPOSIS
run_query_normal
mysql - mysql handle
command - currrent command pointer
flags -flags indicating wheter to SEND and/or REAP
query - query string to execute
query_len - length query string to execute
ds - output buffer wherte to store result form query
RETURN VALUE
error - function will not return
*/
static void run_query_normal(MYSQL *mysql, struct st_query *command,
int flags, char *query, int query_len,
DYNAMIC_STRING *ds, DYNAMIC_STRING *ds_warnings)
{
MYSQL_RES *res= 0;
int err= 0, counter= 0;
DBUG_ENTER("run_query_normal");
DBUG_PRINT("enter",("flags: %d", flags));
DBUG_PRINT("enter", ("query: '%-.60s'", query));
if (flags & QUERY_SEND)
{
/*
Send the query
*/
if (mysql_send_query(mysql, query, query_len))
{
handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
}
if (!(flags & QUERY_REAP))
DBUG_VOID_RETURN;
do
{
/*
When on first result set, call mysql_read_query_result to retrieve
answer to the query sent earlier
*/
if ((counter==0) && mysql_read_query_result(mysql))
{
handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
/*
Store the result. If res is NULL, use mysql_field_count to
determine if that was expected
*/
if (!(res= mysql_store_result(mysql)) && mysql_field_count(mysql))
{
handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
if (!disable_result_log)
{
ulonglong affected_rows; /* Ok to be undef if 'disable_info' is set */
LINT_INIT(affected_rows);
if (res)
{
MYSQL_FIELD *fields= mysql_fetch_fields(res);
uint num_fields= mysql_num_fields(res);
if (display_metadata)
append_metadata(ds, fields, num_fields);
if (!display_result_vertically)
append_table_headings(ds, fields, num_fields);
append_result(ds, res);
}
/*
Need to call mysql_affected_rows() before the "new"
query to find the warnings
*/
if (!disable_info)
affected_rows= mysql_affected_rows(mysql);
/*
Add all warnings to the result. We can't do this if we are in
the middle of processing results from multi-statement, because
this will break protocol.
*/
if (!disable_warnings && !mysql_more_results(mysql))
{
if (append_warnings(ds_warnings, mysql) || ds_warnings->length)
{
dynstr_append_mem(ds, "Warnings:\n", 10);
dynstr_append_mem(ds, ds_warnings->str, ds_warnings->length);
}
}
if (!disable_info)
append_info(ds, affected_rows, mysql_info(mysql));
}
if (res)
mysql_free_result(res);
counter++;
} while (!(err= mysql_next_result(mysql)));
if (err > 0)
{
/* We got an error from mysql_next_result, maybe expected */
handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds);
goto end;
}
DBUG_ASSERT(err == -1); /* Successful and there are no more results */
/* If we come here the query is both executed and read successfully */
handle_no_error(command);
end:
free_replace();
/*
We save the return code (mysql_errno(mysql)) from the last call sent
to the server into the mysqltest builtin variable $mysql_errno. This
variable then can be used from the test case itself.
*/
var_set_errno(mysql_errno(mysql));
DBUG_VOID_RETURN;
}
/*
Handle errors which occurred during execution
SYNOPSIS
handle_error()
query - query string
q - query context
err_errno - error number
err_error - error message
err_sqlstate - sql state
ds - dynamic string which is used for output buffer ds - dynamic string which is used for output buffer
NOTE NOTE
...@@ -3294,13 +3494,12 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -3294,13 +3494,12 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
immediately. immediately.
RETURN VALUE RETURN VALUE
0 - OK error - function will not return
1 - Some other error was expected.
*/ */
static int handle_error(const char *query, struct st_query *q, static void handle_error(const char *query, struct st_query *q,
unsigned int err_errno, const char *err_error, unsigned int err_errno, const char *err_error,
const char* err_sqlstate, DYNAMIC_STRING *ds) const char *err_sqlstate, DYNAMIC_STRING *ds)
{ {
uint i; uint i;
...@@ -3337,7 +3536,7 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3337,7 +3536,7 @@ static int handle_error(const char *query, struct st_query *q,
dynstr_append(ds,"Got one of the listed errors\n"); dynstr_append(ds,"Got one of the listed errors\n");
} }
/* OK */ /* OK */
DBUG_RETURN(0); DBUG_VOID_RETURN;
} }
} }
...@@ -3355,21 +3554,15 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3355,21 +3554,15 @@ static int handle_error(const char *query, struct st_query *q,
if (i) if (i)
{ {
if (q->expected_errno[0].type == ERR_ERRNO) if (q->expected_errno[0].type == ERR_ERRNO)
die("query '%s' failed with wrong errno %d instead of %d...", die("query '%s' failed with wrong errno %d: '%s', instead of %d...",
q->query, err_errno, q->expected_errno[0].code.errnum); q->query, err_errno, err_error, q->expected_errno[0].code.errnum);
else else
die("query '%s' failed with wrong sqlstate %s instead of %s...", die("query '%s' failed with wrong sqlstate %s: '%s', instead of %s...",
q->query, err_sqlstate, q->expected_errno[0].code.sqlstate); q->query, err_sqlstate, err_error,
DBUG_RETURN(1); q->expected_errno[0].code.sqlstate);
} }
/* DBUG_VOID_RETURN;
If we do not abort on error, failure to run the query does not fail the
whole test case.
*/
verbose_msg("query '%s' failed: %d: %s", q->query, err_errno,
err_error);
DBUG_RETURN(0);
} }
...@@ -3381,11 +3574,10 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3381,11 +3574,10 @@ static int handle_error(const char *query, struct st_query *q,
q - context of query q - context of query
RETURN VALUE RETURN VALUE
0 - OK error - function will not return
1 - Some error was expected from this query.
*/ */
static int handle_no_error(struct st_query *q) static void handle_no_error(struct st_query *q)
{ {
DBUG_ENTER("handle_no_error"); DBUG_ENTER("handle_no_error");
...@@ -3395,7 +3587,6 @@ static int handle_no_error(struct st_query *q) ...@@ -3395,7 +3587,6 @@ static int handle_no_error(struct st_query *q)
/* 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("query '%s' succeeded - should have failed with errno %d...", die("query '%s' succeeded - should have failed with errno %d...",
q->query, q->expected_errno[0].code.errnum); q->query, q->expected_errno[0].code.errnum);
DBUG_RETURN(1);
} }
else if (q->expected_errno[0].type == ERR_SQLSTATE && else if (q->expected_errno[0].type == ERR_SQLSTATE &&
strcmp(q->expected_errno[0].code.sqlstate,"00000") != 0) strcmp(q->expected_errno[0].code.sqlstate,"00000") != 0)
...@@ -3403,111 +3594,97 @@ static int handle_no_error(struct st_query *q) ...@@ -3403,111 +3594,97 @@ static int handle_no_error(struct st_query *q)
/* SQLSTATE we wanted was != "00000", i.e. not an expected success */ /* SQLSTATE we wanted was != "00000", i.e. not an expected success */
die("query '%s' succeeded - should have failed with sqlstate %s...", die("query '%s' succeeded - should have failed with sqlstate %s...",
q->query, q->expected_errno[0].code.sqlstate); q->query, q->expected_errno[0].code.sqlstate);
DBUG_RETURN(1);
} }
DBUG_RETURN(0); DBUG_VOID_RETURN;
} }
/****************************************************************************\
* If --ps-protocol run ordinary statements using prepared statemnt C API
\****************************************************************************/
/* /*
We don't have a mysql_stmt_send_execute() so we only handle Run query using prepared statement C API
complete SEND+REAP
SYNPOSIS
run_query_stmt
mysql - mysql handle
command - currrent command pointer
query - query string to execute
query_len - length query string to execute
ds - output buffer wherte to store result form query
RETURN VALUE
error - function will not return
*/ */
static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) static void run_query_stmt(MYSQL *mysql, struct st_query *command,
char *query, int query_len, DYNAMIC_STRING *ds,
DYNAMIC_STRING *ds_warnings)
{ {
int error= 0; /* Function return code if "goto end;" */
int err; /* Temporary storage of return code from calls */
int query_len;
ulonglong num_rows;
char *query;
MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */ MYSQL_RES *res= NULL; /* Note that here 'res' is meta data result set */
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_tmp;
DYNAMIC_STRING eval_query;
MYSQL_STMT *stmt; MYSQL_STMT *stmt;
DYNAMIC_STRING ds_prepare_warnings;
DYNAMIC_STRING ds_execute_warnings;
DBUG_ENTER("run_query_stmt"); DBUG_ENTER("run_query_stmt");
DBUG_PRINT("query", ("'%-.60s'", query));
/* /*
We must allocate a new stmt for each query in this program becasue this Init a new stmt if it's not alreday one created for this connectoon
may be a new connection.
*/ */
if (!(stmt= mysql_stmt_init(mysql))) if(!(stmt= cur_con->stmt))
die("unable init stmt structure");
if (q->type != Q_EVAL)
{
query= q->query;
query_len= strlen(query);
}
else
{
init_dynamic_string(&eval_query, "", 16384, 65536);
do_eval(&eval_query, q->query);
query= eval_query.str;
query_len= eval_query.length;
}
DBUG_PRINT("query", ("'%-.60s'", query));
if (q->record_file[0])
{ {
init_dynamic_string(&ds_tmp, "", 16384, 65536); if (!(stmt= mysql_stmt_init(mysql)))
ds= &ds_tmp; die("unable to init stmt structure");
cur_con->stmt= stmt;
} }
else
ds= &ds_res;
/* Store the query into the output buffer if not disabled */ /* Init dynamic strings for warnings */
if (!disable_query_log) if (!disable_warnings)
{ {
replace_dynstr_append_mem(ds,query, query_len); init_dynamic_string(&ds_prepare_warnings, NULL, 0, 256);
dynstr_append_mem(ds, delimiter, delimiter_length); init_dynamic_string(&ds_execute_warnings, NULL, 0, 256);
dynstr_append_mem(ds, "\n", 1);
} }
/* /*
We use the prepared statement interface but there is actually no Prepare the query
'?' in the query. If unpreparable we fall back to use normal
C API.
*/ */
if ((err= mysql_stmt_prepare(stmt, query, query_len)) == CR_NO_PREPARE_STMT) if (mysql_stmt_prepare(stmt, query, query_len))
return run_query_normal(mysql, q, flags);
if (err != 0)
{ {
/* handle_error(query, command, mysql_stmt_errno(stmt),
Preparing is part of normal execution and some errors may be expected mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
*/
if (handle_error(query, q, mysql_stmt_errno(stmt),
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds))
error= 1;
goto end; goto end;
} }
/* We may have got warnings already, collect them if any */ /*
if (!disable_ps_warnings) Get the warnings from mysql_stmt_prepare and keep them in a
run_query_stmt_handle_warnings(mysql, ds); separate string
*/
if (!disable_warnings)
append_warnings(&ds_prepare_warnings, mysql);
/* /*
No need to call mysql_stmt_bind_param() because we have no No need to call mysql_stmt_bind_param() because we have no
parameter markers. parameter markers.
*/
To optimize performance we use a global 'stmt' that is initiated #ifdef BUG14013_FIXED
once. A new prepare will implicitely close the old one. When we /*
terminate we will lose the connection, this also closes the last Use cursor when retrieving result
prepared statement.
*/ */
if (cursor_protocol_enabled)
{
ulong type= CURSOR_TYPE_READ_ONLY;
if (mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type))
die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
}
#endif
if (mysql_stmt_execute(stmt) != 0) /* 0 == Success */ /*
Execute the query
*/
if (mysql_stmt_execute(stmt))
{ {
/* We got an error, maybe expected */ handle_error(query, command, mysql_stmt_errno(stmt),
if (handle_error(query, q, mysql_stmt_errno(stmt), mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds))
error= 1;
goto end; goto end;
} }
...@@ -3518,313 +3695,387 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) ...@@ -3518,313 +3695,387 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags)
*/ */
{ {
my_bool one= 1; my_bool one= 1;
if ((err= mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, if (mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*) &one))
(void*) &one)) != 0) die("mysql_stmt_attr_set(STMT_ATTR_UPDATE_MAX_LENGTH) failed': %d %s",
die("unable to set stmt attribute " mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
"'STMT_ATTR_UPDATE_MAX_LENGTH' err: %d", err);
} }
/* /*
If we got here the statement succeeded and was expected to do so, If we got here the statement succeeded and was expected to do so,
get data. Note that this can still give errors found during execution! get data. Note that this can still give errors found during execution!
*/ */
if ((err= mysql_stmt_store_result(stmt)) != 0) if (mysql_stmt_store_result(stmt))
{ {
/* We got an error, maybe expected */ handle_error(query, command, mysql_stmt_errno(stmt),
if(handle_error(query, q, mysql_stmt_errno(stmt), mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds);
mysql_stmt_error(stmt), mysql_stmt_sqlstate(stmt), ds))
error = 1;
goto end; goto end;
} }
/* If we got here the statement was both executed and read succeesfully */ /* If we got here the statement was both executed and read succeesfully */
if (handle_no_error(q)) handle_no_error(command);
if (!disable_result_log)
{ {
error= 1;
goto end;
}
num_rows= mysql_stmt_num_rows(stmt);
/* /*
Not all statements creates a result set. If there is one we can Not all statements creates a result set. If there is one we can
now create another normal result set that contains the meta now create another normal result set that contains the meta
data. This set can be handled almost like any other non prepared data. This set can be handled almost like any other non prepared
statement result set. statement result set.
*/ */
if (!disable_result_log && ((res= mysql_stmt_result_metadata(stmt)) != NULL)) if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
{ {
/* Take the column count from meta info */ /* Take the column count from meta info */
MYSQL_FIELD *field= mysql_fetch_fields(res); MYSQL_FIELD *fields= mysql_fetch_fields(res);
uint num_fields= mysql_num_fields(res); uint num_fields= mysql_num_fields(res);
if (display_metadata) if (display_metadata)
run_query_display_metadata(field, num_fields, ds); append_metadata(ds, fields, num_fields);
if (!display_result_vertically) if (!display_result_vertically)
append_table_headings(ds, fields, num_fields);
append_stmt_result(ds, stmt, fields, num_fields);
mysql_free_result(res); /* Free normal result set with meta data */
/* Clear prepare warnings */
dynstr_set(&ds_prepare_warnings, NULL);
}
else
{ {
/* Display the table heading with the names tab separated */ /*
uint col_idx; This is a query without resultset
for (col_idx= 0; col_idx < num_fields; col_idx++) */
}
if (!disable_warnings)
{ {
if (col_idx) /* Get the warnings from execute */
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append(ds, field[col_idx].name); /* Append warnings to ds - if there are any */
if (append_warnings(&ds_execute_warnings, mysql) ||
ds_prepare_warnings.length ||
ds_warnings->length)
{
dynstr_append_mem(ds, "Warnings:\n", 10);
if (ds_warnings->length)
dynstr_append_mem(ds, ds_warnings->str,
ds_warnings->length);
if (ds_prepare_warnings.length)
dynstr_append_mem(ds, ds_prepare_warnings.str,
ds_prepare_warnings.length);
if (ds_execute_warnings.length)
dynstr_append_mem(ds, ds_execute_warnings.str,
ds_execute_warnings.length);
} }
dynstr_append_mem(ds, "\n", 1);
} }
/* Now we are to put the real result into the output buffer */ if (!disable_info)
/* FIXME when it works, create function append_stmt_result() */ append_info(ds, mysql_affected_rows(mysql), mysql_info(mysql));
{
MYSQL_BIND *bind;
my_bool *is_null;
unsigned long *length;
/* FIXME we don't handle vertical display ..... */
uint col_idx, row_idx;
/* Allocate array with bind structs, lengths and NULL flags */ }
bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND),
MYF(MY_WME | MY_FAE | MY_ZEROFILL));
length= (unsigned long*) my_malloc(num_fields * sizeof(unsigned long),
MYF(MY_WME | MY_FAE));
is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool),
MYF(MY_WME | MY_FAE));
for (col_idx= 0; col_idx < num_fields; col_idx++) end:
free_replace();
if (!disable_warnings)
{ {
/* Allocate data for output */ dynstr_free(&ds_prepare_warnings);
dynstr_free(&ds_execute_warnings);
}
/* /*
FIXME it may be a bug that for non string/blob types We save the return code (mysql_stmt_errno(stmt)) from the last call sent
'max_length' is 0, should try out 'length' in that case to the server into the mysqltest builtin variable $mysql_errno. This
variable then can be used from the test case itself.
*/ */
uint max_length= max(field[col_idx].max_length + 1, 1024); var_set_errno(mysql_stmt_errno(stmt));
char *str_data= (char *) my_malloc(max_length, MYF(MY_WME | MY_FAE)); #ifndef BUG15518_FIXED
mysql_stmt_close(stmt);
cur_con->stmt= NULL;
#endif
DBUG_VOID_RETURN;
}
bind[col_idx].buffer_type= MYSQL_TYPE_STRING;
bind[col_idx].buffer= (char *)str_data;
bind[col_idx].buffer_length= max_length;
bind[col_idx].is_null= &is_null[col_idx];
bind[col_idx].length= &length[col_idx];
}
/* Fill in the data into the structures created above */
if ((err= mysql_stmt_bind_result(stmt, bind)) != 0)
die("unable to bind result to statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
/* Read result from each row */ /*
for (row_idx= 0; row_idx < num_rows; row_idx++) Create a util connection if one does not already exists
and use that to run the query
This is done to avoid implict commit when creating/dropping objects such
as view, sp etc.
*/
static int util_query(MYSQL* org_mysql, const char* query){
MYSQL* mysql;
DBUG_ENTER("util_query");
if(!(mysql= cur_con->util_mysql))
{ {
if ((err= mysql_stmt_fetch(stmt)) != 0) DBUG_PRINT("info", ("Creating util_mysql"));
die("unable to fetch all rows from statement '%s': " if (!(mysql= mysql_init(mysql)))
"%s (mysql_stmt_errno=%d returned=%d)", die("Failed in mysql_init()");
query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
/* Read result from each column */ if (safe_connect(mysql, org_mysql->host, org_mysql->user,
for (col_idx= 0; col_idx < num_fields; col_idx++) org_mysql->passwd, org_mysql->db, org_mysql->port,
org_mysql->unix_socket))
die("Could not open util connection: %d %s",
mysql_errno(mysql), mysql_error(mysql));
cur_con->util_mysql= mysql;
}
return mysql_query(mysql, query);
}
/*
Run query
flags control the phased/stages of query execution to be performed
if QUERY_SEND bit is on, the query will be sent. If QUERY_REAP is on
the result will be read - for regular query, both bits must be on
SYNPOSIS
run_query
mysql - mysql handle
command - currrent command pointer
*/
static void run_query(MYSQL *mysql, struct st_query *command, int flags)
{
DYNAMIC_STRING *ds;
DYNAMIC_STRING ds_result;
DYNAMIC_STRING ds_warnings;
DYNAMIC_STRING eval_query;
char *query;
int query_len;
my_bool view_created= 0, sp_created= 0;
my_bool complete_query= ((flags & QUERY_SEND) && (flags & QUERY_REAP));
init_dynamic_string(&ds_warnings, NULL, 0, 256);
/*
Evaluate query if this is an eval command
*/
if (command->type == Q_EVAL)
{ {
const char *val; init_dynamic_string(&eval_query, "", 16384, 65536);
ulonglong len; do_eval(&eval_query, command->query);
if (col_idx < max_replace_column && replace_column[col_idx]) query = eval_query.str;
query_len = eval_query.length;
}
else
{ {
val= replace_column[col_idx]; query = command->query;
len= strlen(val); query_len = strlen(query);
} }
else if (*bind[col_idx].is_null)
/*
When command->record_file is set the output of _this_ query
should be compared with an already existing file
Create a temporary dynamic string to contain the output from
this query.
*/
if (command->record_file[0])
{ {
val= "NULL"; init_dynamic_string(&ds_result, "", 16384, 65536);
len= 4; ds= &ds_result;
} }
else else
ds= &ds_res;
/*
Log the query into the output buffer
*/
if (!disable_query_log && (flags & QUERY_SEND))
{ {
/* FIXME is string terminated? */ replace_dynstr_append_mem(ds, query, query_len);
val= (const char *) bind[col_idx].buffer; dynstr_append_mem(ds, delimiter, delimiter_length);
len= *bind[col_idx].length; dynstr_append_mem(ds, "\n", 1);
} }
if (!display_result_vertically)
if (view_protocol_enabled &&
complete_query &&
match_re(&view_re, query))
{ {
if (col_idx) /* No tab before first col */ /*
dynstr_append_mem(ds, "\t", 1); Create the query as a view.
replace_dynstr_append_mem(ds, val, (int)len); Use replace since view can exist from a failed mysqltest run
*/
DYNAMIC_STRING query_str;
init_dynamic_string(&query_str,
"CREATE OR REPLACE VIEW mysqltest_tmp_v AS ",
query_len+64, 256);
dynstr_append_mem(&query_str, query, query_len);
if (util_query(mysql, query_str.str))
{
/*
Failed to create the view, this is not fatal
just run the query the normal way
*/
DBUG_PRINT("view_create_error",
("Failed to create view '%s': %d: %s", query_str.str,
mysql_errno(mysql), mysql_error(mysql)));
/* Log error to create view */
verbose_msg("Failed to create view '%s' %d: %s", query_str.str,
mysql_errno(mysql), mysql_error(mysql));
} }
else else
{ {
dynstr_append(ds, field[col_idx].name); /*
dynstr_append_mem(ds, "\t", 1); Yes, it was possible to create this query as a view
replace_dynstr_append_mem(ds, val, (int)len); */
dynstr_append_mem(ds, "\n", 1); view_created= 1;
} query= (char*)"SELECT * FROM mysqltest_tmp_v";
query_len = strlen(query);
/*
Collect warnings from create of the view that should otherwise
have been produced when the SELECT was executed
*/
append_warnings(&ds_warnings, cur_con->util_mysql);
} }
if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1); dynstr_free(&query_str);
} }
if ((err= mysql_stmt_fetch(stmt)) != MYSQL_NO_DATA) if (sp_protocol_enabled &&
die("fetch didn't end with MYSQL_NO_DATA from statement " complete_query &&
"'%s': %s (mysql_stmt_errno=%d returned=%d)", match_re(&sp_re, query))
query, {
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err); /*
Create the query as a stored procedure
Drop first since sp can exist from a failed mysqltest run
*/
DYNAMIC_STRING query_str;
init_dynamic_string(&query_str,
"DROP PROCEDURE IF EXISTS mysqltest_tmp_sp;",
query_len+64, 256);
util_query(mysql, query_str.str);
dynstr_set(&query_str, "CREATE PROCEDURE mysqltest_tmp_sp()\n");
dynstr_append_mem(&query_str, query, query_len);
if (util_query(mysql, query_str.str))
{
/*
Failed to create the stored procedure for this query,
this is not fatal just run the query the normal way
*/
DBUG_PRINT("sp_create_error",
("Failed to create sp '%s': %d: %s", query_str.str,
mysql_errno(mysql), mysql_error(mysql)));
free_replace_column(); /* Log error to create sp */
verbose_msg("Failed to create sp '%s' %d: %s", query_str.str,
mysql_errno(mysql), mysql_error(mysql));
for (col_idx= 0; col_idx < num_fields; col_idx++) }
else
{ {
/* Free data for output */ sp_created= 1;
my_free((gptr)bind[col_idx].buffer, MYF(MY_WME | MY_FAE));
query= (char*)"CALL mysqltest_tmp_sp()";
query_len = strlen(query);
} }
/* Free array with bind structs, lengths and NULL flags */ dynstr_free(&query_str);
my_free((gptr)bind , MYF(MY_WME | MY_FAE));
my_free((gptr)length , MYF(MY_WME | MY_FAE));
my_free((gptr)is_null , MYF(MY_WME | MY_FAE));
} }
/* Add all warnings to the result */ /*
run_query_stmt_handle_warnings(mysql, ds); Find out how to run this query
if (!disable_info) Always run with normal C API if it's not a complete
{ SEND + REAP
char buf[40];
sprintf(buf,"affected rows: %lu\n",(ulong) mysql_affected_rows(mysql)); If it is a '?' in the query it may be a SQL level prepared
dynstr_append(ds, buf); statement already and we can't do it twice
if (mysql_info(mysql)) */
if (ps_protocol_enabled &&
complete_query &&
match_re(&ps_re, query))
run_query_stmt(mysql, command, query, query_len, ds, &ds_warnings);
else
run_query_normal(mysql, command, flags, query, query_len,
ds, &ds_warnings);
if (sp_created)
{ {
dynstr_append(ds, "info: "); if (util_query(mysql, "DROP PROCEDURE mysqltest_tmp_sp "))
dynstr_append(ds, mysql_info(mysql)); die("Failed to drop sp: %d: %s", mysql_errno(mysql), mysql_error(mysql));
dynstr_append_mem(ds, "\n", 1);
}
} }
if (view_created)
{
if (util_query(mysql, "DROP VIEW mysqltest_tmp_v "))
die("Failed to drop view: %d: %s",
mysql_errno(mysql), mysql_error(mysql));
} }
run_query_stmt_handle_warnings(mysql, ds);
if (command->record_file[0])
{
/* A result file was specified for _this_ query */
if (record) if (record)
{ {
if (!q->record_file[0] && !result_file) /*
die("Missing result file"); Recording in progress
if (!result_file) Dump the output from _this_ query to the specified record_file
str_to_file(q->record_file, ds->str, ds->length); */
str_to_file(command->record_file, ds->str, ds->length);
} else {
/*
The output from _this_ query should be checked against an already
existing file which has been specified using --require or --result
*/
check_result(ds, command->record_file, command->require_file);
} }
else if (q->record_file[0])
{
error= check_result(ds, q->record_file, q->require_file);
} }
if (res)
mysql_free_result(res); /* Free normal result set with meta data */
last_result= 0; /* FIXME have no idea what this is about... */
end: dynstr_free(&ds_warnings);
free_replace(); if (ds == &ds_result)
last_result=0; dynstr_free(&ds_result);
if (ds == &ds_tmp) if (command->type == Q_EVAL)
dynstr_free(&ds_tmp);
if (q->type == Q_EVAL)
dynstr_free(&eval_query); dynstr_free(&eval_query);
var_set_errno(mysql_stmt_errno(stmt));
mysql_stmt_close(stmt);
DBUG_RETURN(error);
} }
/****************************************************************************\ /****************************************************************************\
* Broken out sub functions to run_query_stmt() * Functions to detect different SQL statements
\****************************************************************************/ \****************************************************************************/
static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields, static char *re_eprint(int err)
DYNAMIC_STRING *ds)
{ {
MYSQL_FIELD *field_end; static char epbuf[100];
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t" size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL,
"Column_alias\tType\tLength\tMax length\tIs_null\t" epbuf, sizeof(epbuf));
"Flags\tDecimals\tCharsetnr\n"); assert(len <= sizeof(epbuf));
return(epbuf);
for (field_end= field+num_fields ;
field < field_end ;
field++)
{
char buff[22];
dynstr_append_mem(ds, field->catalog,
field->catalog_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->db, field->db_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_table,
field->org_table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->table,
field->table_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->org_name,
field->org_name_length);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, field->name, field->name_length);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->type, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
longlong10_to_str((unsigned int) field->length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
longlong10_to_str((unsigned int) field->max_length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?
"N" : "Y"), 1);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->flags, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->decimals, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->charsetnr, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\n", 1);
}
} }
static void init_re_comp(my_regex_t *re, const char* str)
static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds)
{ {
uint count; int err= my_regcomp(re, str, (REG_EXTENDED | REG_ICASE | REG_NOSUB),
DBUG_ENTER("run_query_stmt_handle_warnings"); &my_charset_latin1);
if (err)
if (!disable_warnings && (count= mysql_warning_count(mysql)))
{
/*
If one day we will support execution of multi-statements
through PS API we should not issue SHOW WARNINGS until
we have not read all results...
*/
DBUG_ASSERT(!mysql_more_results(mysql));
if (mysql_real_query(mysql, "SHOW WARNINGS", 13) == 0)
{
MYSQL_RES *warn_res= mysql_store_result(mysql);
if (!warn_res)
die("Warning count is %u but didn't get any warnings",
count);
else
{ {
dynstr_append_mem(ds, "Warnings:\n", 10); char erbuf[100];
append_result(ds, warn_res); int len= my_regerror(err, re, erbuf, sizeof(erbuf));
mysql_free_result(warn_res); die("error %s, %d/%d `%s'\n",
} re_eprint(err), len, (int)sizeof(erbuf), erbuf);
}
} }
DBUG_VOID_RETURN;
} }
static void init_re(void)
/****************************************************************************\
* Functions to match SQL statements that can be prepared
\****************************************************************************/
static void ps_init_re(void)
{ {
/*
Filter for queries that can be run using the
MySQL Prepared Statements C API
*/
const char *ps_re_str = const char *ps_re_str =
"^(" "^("
"[[:space:]]*REPLACE[[:space:]]|" "[[:space:]]*REPLACE[[:space:]]|"
...@@ -3839,50 +4090,49 @@ static void ps_init_re(void) ...@@ -3839,50 +4090,49 @@ static void ps_init_re(void)
"[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|" "[[:space:]]*UPDATE[[:space:]]+MULTI[[:space:]]|"
"[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])"; "[[:space:]]*INSERT[[:space:]]+SELECT[[:space:]])";
int err= my_regcomp(&ps_re, ps_re_str, /*
(REG_EXTENDED | REG_ICASE | REG_NOSUB), Filter for queries that can be run using the
&my_charset_latin1); Stored procedures
if (err) */
{ const char *sp_re_str =ps_re_str;
char erbuf[100];
int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf)); /*
fprintf(stderr, "error %s, %d/%d `%s'\n", Filter for queries that can be run as views
ps_eprint(err), len, (int)sizeof(erbuf), erbuf); */
exit(1); const char *view_re_str =
} "^("
"[[:space:]]*SELECT[[:space:]])";
init_re_comp(&ps_re, ps_re_str);
init_re_comp(&sp_re, sp_re_str);
init_re_comp(&view_re, view_re_str);
} }
static int ps_match_re(char *stmt_str) static int match_re(my_regex_t *re, char *str)
{ {
int err= my_regexec(&ps_re, stmt_str, (size_t)0, NULL, 0); int err= my_regexec(re, str, (size_t)0, NULL, 0);
if (err == 0) if (err == 0)
return 1; return 1;
else if (err == REG_NOMATCH) else if (err == REG_NOMATCH)
return 0; return 0;
else
{ {
char erbuf[100]; char erbuf[100];
int len= my_regerror(err, &ps_re, erbuf, sizeof(erbuf)); int len= my_regerror(err, re, erbuf, sizeof(erbuf));
fprintf(stderr, "error %s, %d/%d `%s'\n", die("error %s, %d/%d `%s'\n",
ps_eprint(err), len, (int)sizeof(erbuf), erbuf); re_eprint(err), len, (int)sizeof(erbuf), erbuf);
exit(1);
} }
return 0;
} }
static char *ps_eprint(int err) static void free_re(void)
{
static char epbuf[100];
size_t len= my_regerror(REG_ITOA|err, (my_regex_t *)NULL, epbuf, sizeof(epbuf));
assert(len <= sizeof(epbuf));
return(epbuf);
}
static void ps_free_reg(void)
{ {
my_regfree(&ps_re); my_regfree(&ps_re);
my_regfree(&sp_re);
my_regfree(&view_re);
my_regex_end();
} }
/****************************************************************************/ /****************************************************************************/
...@@ -3917,6 +4167,7 @@ void get_query_type(struct st_query* q) ...@@ -3917,6 +4167,7 @@ void get_query_type(struct st_query* q)
q->type= Q_COMMENT; q->type= Q_COMMENT;
} }
else if (q->type == Q_COMMENT_WITH_COMMAND && else if (q->type == Q_COMMENT_WITH_COMMAND &&
q->first_word_len &&
q->query[q->first_word_len-1] == ';') q->query[q->first_word_len-1] == ';')
{ {
/* /*
...@@ -3965,12 +4216,10 @@ static VAR *var_init(VAR *v, const char *name, int name_len, const char *val, ...@@ -3965,12 +4216,10 @@ static VAR *var_init(VAR *v, const char *name, int name_len, const char *val,
if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME)))) if (!(tmp_var->str_val = my_malloc(val_alloc_len+1, MYF(MY_WME))))
die("Out of memory"); die("Out of memory");
memcpy(tmp_var->name, name, name_len); if (name)
strmake(tmp_var->name, name, name_len);
if (val) if (val)
{ strmake(tmp_var->str_val, val, val_len);
memcpy(tmp_var->str_val, val, val_len);
tmp_var->str_val[val_len]=0;
}
tmp_var->name_len = name_len; tmp_var->name_len = name_len;
tmp_var->str_val_len = val_len; tmp_var->str_val_len = val_len;
tmp_var->alloced_len = val_alloc_len; tmp_var->alloced_len = val_alloc_len;
...@@ -4012,8 +4261,7 @@ static void init_var_hash(MYSQL *mysql) ...@@ -4012,8 +4261,7 @@ static void init_var_hash(MYSQL *mysql)
v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0); v= var_init(0,"MAX_TABLES", 0, (sizeof(ulong) == 4) ? "31" : "62",0);
my_hash_insert(&var_hash, (byte*) v); my_hash_insert(&var_hash, (byte*) v);
v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0); v= var_init(0,"SERVER_VERSION", 0, mysql_get_server_info(mysql), 0);
my_hash_insert(&var_hash, (byte*) v); my_hash_insert(&var_hash, (byte*) v); v= var_init(0,"DB", 2, db, 0);
v= var_init(0,"DB", 2, db, 0);
my_hash_insert(&var_hash, (byte*) v); my_hash_insert(&var_hash, (byte*) v);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
...@@ -4021,7 +4269,6 @@ static void init_var_hash(MYSQL *mysql) ...@@ -4021,7 +4269,6 @@ static void init_var_hash(MYSQL *mysql)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int error = 0;
struct st_query *q; struct st_query *q;
my_bool require_file=0, q_send_flag=0, abort_flag= 0, my_bool require_file=0, q_send_flag=0, abort_flag= 0,
query_executed= 0; query_executed= 0;
...@@ -4071,11 +4318,15 @@ int main(int argc, char **argv) ...@@ -4071,11 +4318,15 @@ int main(int argc, char **argv)
if (manager_host) if (manager_host)
init_manager(); init_manager();
#endif #endif
if (ps_protocol) init_re();
{ ps_protocol_enabled= ps_protocol;
sp_protocol_enabled= sp_protocol;
view_protocol_enabled= view_protocol;
cursor_protocol_enabled= cursor_protocol;
/* Cursor protcol implies ps protocol */
if (cursor_protocol_enabled)
ps_protocol_enabled= 1; ps_protocol_enabled= 1;
ps_init_re();
}
if (!( mysql_init(&cur_con->mysql))) if (!( mysql_init(&cur_con->mysql)))
die("Failed in mysql_init()"); die("Failed in mysql_init()");
if (opt_compress) if (opt_compress)
...@@ -4093,7 +4344,8 @@ int main(int argc, char **argv) ...@@ -4093,7 +4344,8 @@ int main(int argc, char **argv)
die("Out of memory"); die("Out of memory");
if (safe_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock)) if (safe_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock))
die("Failed in mysql_real_connect(): %s", mysql_error(&cur_con->mysql)); die("Could not open connection '%s': %d %s", cur_con->name,
mysql_errno(&cur_con->mysql), mysql_error(&cur_con->mysql));
init_var_hash(&cur_con->mysql); init_var_hash(&cur_con->mysql);
...@@ -4115,7 +4367,7 @@ int main(int argc, char **argv) ...@@ -4115,7 +4367,7 @@ int main(int argc, char **argv)
processed = 1; processed = 1;
switch (q->type) { switch (q->type) {
case Q_CONNECT: case Q_CONNECT:
error|= do_connect(q); do_connect(q);
break; break;
case Q_CONNECTION: select_connection(q); break; case Q_CONNECTION: select_connection(q); break;
case Q_DISCONNECT: case Q_DISCONNECT:
...@@ -4149,7 +4401,7 @@ int main(int argc, char **argv) ...@@ -4149,7 +4401,7 @@ int main(int argc, char **argv)
#endif #endif
case Q_INC: do_modify_var(q, "inc", DO_INC); 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_DEC: do_modify_var(q, "dec", DO_DEC); break;
case Q_ECHO: do_echo(q); break; case Q_ECHO: do_echo(q); query_executed= 1; 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);
...@@ -4176,15 +4428,6 @@ int main(int argc, char **argv) ...@@ -4176,15 +4428,6 @@ int main(int argc, char **argv)
case Q_QUERY_HORIZONTAL: case Q_QUERY_HORIZONTAL:
{ {
my_bool old_display_result_vertically= display_result_vertically; my_bool old_display_result_vertically= display_result_vertically;
if (!q->query[q->first_word_len])
{
/* This happens when we use 'query_..' on it's own line */
q_send_flag=1;
DBUG_PRINT("info",
("query: '%s' first_word_len: %d send_flag=1",
q->query, q->first_word_len));
break;
}
/* fix up query pointer if this is * first iteration for this line */ /* fix up query pointer if this is * first iteration for this line */
if (q->query == q->query_buf) if (q->query == q->query_buf)
q->query += q->first_word_len + 1; q->query += q->first_word_len + 1;
...@@ -4195,7 +4438,7 @@ int main(int argc, char **argv) ...@@ -4195,7 +4438,7 @@ int main(int argc, char **argv)
q->require_file=require_file; q->require_file=require_file;
save_file[0]=0; save_file[0]=0;
} }
error|= run_query(&cur_con->mysql, q, QUERY_REAP|QUERY_SEND); 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; q->last_argument= q->end;
query_executed= 1; query_executed= 1;
...@@ -4222,7 +4465,7 @@ int main(int argc, char **argv) ...@@ -4222,7 +4465,7 @@ int main(int argc, char **argv)
q->require_file=require_file; q->require_file=require_file;
save_file[0]=0; save_file[0]=0;
} }
error |= run_query(&cur_con->mysql, q, flags); run_query(&cur_con->mysql, q, flags);
query_executed= 1; query_executed= 1;
q->last_argument= q->end; q->last_argument= q->end;
break; break;
...@@ -4243,7 +4486,7 @@ int main(int argc, char **argv) ...@@ -4243,7 +4486,7 @@ int main(int argc, char **argv)
query and read the result some time later when reap instruction query and read the result some time later when reap instruction
is given on this connection. is given on this connection.
*/ */
error |= run_query(&cur_con->mysql, q, QUERY_SEND); run_query(&cur_con->mysql, q, QUERY_SEND);
query_executed= 1; query_executed= 1;
q->last_argument= q->end; q->last_argument= q->end;
break; break;
...@@ -4365,49 +4608,65 @@ int main(int argc, char **argv) ...@@ -4365,49 +4608,65 @@ int main(int argc, char **argv)
parser.current_line += current_line_inc; parser.current_line += current_line_inc;
} }
if (!query_executed && result_file && my_stat(result_file, &res_info, 0))
{
/* /*
my_stat() successful on result file. Check if we have not run a The whole test has been executed _sucessfully_
single query, but we do have a result file that contains data. Time to compare result or save it to record file
Note that we don't care, if my_stat() fails. For example for The entire output from test is now kept in ds_res
non-existing or non-readable file we assume it's fine to have
no query output from the test file, e.g. regarded as no error.
*/ */
if (res_info.st_size) if (ds_res.length)
error|= (RESULT_CONTENT_MISMATCH | RESULT_LENGTH_MISMATCH);
}
if (ds_res.length && !error)
{ {
if (result_file) if (result_file)
{ {
if (!record) if (record)
error |= check_result(&ds_res, result_file, q->require_file); {
else /* Dump the output from test to result file */
str_to_file(result_file, ds_res.str, ds_res.length); str_to_file(result_file, ds_res.str, ds_res.length);
} }
else else
{ {
/* Print the result to stdout */ /* Check that the output from test is equal to result file
- detect missing result file
- detect zero size result file
*/
check_result(&ds_res, result_file, 0);
}
}
else
{
/* No result_file specified to compare with, print to stdout */
printf("%s", ds_res.str); printf("%s", ds_res.str);
} }
} }
dynstr_free(&ds_res); else
{
die("The test didn't produce any output");
}
if (!silent) if (!query_executed && result_file && my_stat(result_file, &res_info, 0))
{ {
if (error) /*
printf("not ok\n"); my_stat() successful on result file. Check if we have not run a
else single query, but we do have a result file that contains data.
printf("ok\n"); Note that we don't care, if my_stat() fails. For example for
non-existing or non-readable file we assume it's fine to have
no query output from the test file, e.g. regarded as no error.
*/
die("No queries executed but result file found!");
} }
dynstr_free(&ds_res);
if (!got_end_timer) if (!got_end_timer)
timer_output(); /* No end_timer cmd, end it */ timer_output(); /* No end_timer cmd, end it */
free_used_memory(); free_used_memory();
my_end(MY_CHECK_ERROR); my_end(MY_CHECK_ERROR);
exit(error ? 1 : 0);
return error ? 1 : 0; /* Keep compiler happy */ /* Yes, if we got this far the test has suceeded! Sakila smiles */
if (!silent)
printf("ok\n");
exit(0);
return 0; /* Keep compiler happy */
} }
...@@ -5204,12 +5463,6 @@ static int initialize_replace_buffer(void) ...@@ -5204,12 +5463,6 @@ static int initialize_replace_buffer(void)
return 0; return 0;
} }
static void free_replace_buffer(void)
{
my_free(out_buff,MYF(MY_WME));
}
/**************************************************************************** /****************************************************************************
Replace results for a column Replace results for a column
*****************************************************************************/ *****************************************************************************/
...@@ -5367,3 +5620,5 @@ FILE *my_popen(const char *cmd, const char *mode __attribute__((unused))) ...@@ -5367,3 +5620,5 @@ FILE *my_popen(const char *cmd, const char *mode __attribute__((unused)))
} }
#endif /* __NETWARE__ or __WIN__*/ #endif /* __NETWARE__ or __WIN__*/
...@@ -9,8 +9,8 @@ disable_query_log; ...@@ -9,8 +9,8 @@ disable_query_log;
drop table if exists t1, t2; drop table if exists t1, t2;
--enable_warnings --enable_warnings
flush tables; flush tables;
@r/have_ndb.require show variables like "have_ndbcluster"; --require r/have_ndb.require
# @r/server_id.require show variables like "server_id"; show variables like "have_ndbcluster";
enable_query_log; enable_query_log;
# Check that server2 has NDB support # Check that server2 has NDB support
...@@ -20,8 +20,8 @@ disable_query_log; ...@@ -20,8 +20,8 @@ disable_query_log;
drop table if exists t1, t2; drop table if exists t1, t2;
--enable_warnings --enable_warnings
flush tables; flush tables;
@r/have_ndb.require show variables like "have_ndbcluster"; --require r/have_ndb.require
# @r/server_id1.require show variables like "server_id"; show variables like "have_ndbcluster";
enable_query_log; enable_query_log;
# Set the default connection to 'server1' # Set the default connection to 'server1'
......
...@@ -8,7 +8,8 @@ connection slave; ...@@ -8,7 +8,8 @@ connection slave;
--disable_warnings --disable_warnings
stop slave; stop slave;
--enable_warnings --enable_warnings
@r/slave-stopped.result show status like 'Slave_running'; --require r/slave-stopped.result
show status like 'Slave_running';
connection master; connection master;
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
...@@ -21,7 +22,8 @@ reset slave; ...@@ -21,7 +22,8 @@ reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
--enable_warnings --enable_warnings
start slave; start slave;
@r/slave-running.result show status like 'Slave_running'; --require r/slave-running.result
show status like 'Slave_running';
# Set the default connection to 'master' # Set the default connection to 'master'
connection master; connection master;
...@@ -52,7 +52,6 @@ execute stmt1; ...@@ -52,7 +52,6 @@ execute stmt1;
##### parameter used for keyword like SELECT (must fail) ##### parameter used for keyword like SELECT (must fail)
set @arg00='SELECT' ; set @arg00='SELECT' ;
# mysqltest gives no output for the next statement, Why ??
--error 1064 --error 1064
@arg00 a from t1 where a=1; @arg00 a from t1 where a=1;
--error 1064 --error 1064
......
...@@ -152,6 +152,7 @@ our $path_client_bindir; ...@@ -152,6 +152,7 @@ our $path_client_bindir;
our $path_language; our $path_language;
our $path_timefile; our $path_timefile;
our $path_manager_log; # Used by mysqldadmin our $path_manager_log; # Used by mysqldadmin
our $path_mysqltest_log;
our $path_slave_load_tmpdir; # What is this?! our $path_slave_load_tmpdir; # What is this?!
our $path_my_basedir; our $path_my_basedir;
our $opt_vardir; # A path but set directly on cmd line our $opt_vardir; # A path but set directly on cmd line
...@@ -193,6 +194,9 @@ our $opt_ssl; ...@@ -193,6 +194,9 @@ our $opt_ssl;
our $opt_skip_ssl; our $opt_skip_ssl;
our $opt_ssl_supported; our $opt_ssl_supported;
our $opt_ps_protocol; our $opt_ps_protocol;
our $opt_sp_protocol;
our $opt_cursor_protocol;
our $opt_view_protocol;
our $opt_current_test; our $opt_current_test;
our $opt_ddd; our $opt_ddd;
...@@ -268,6 +272,7 @@ our $opt_user; ...@@ -268,6 +272,7 @@ our $opt_user;
our $opt_user_test; our $opt_user_test;
our $opt_valgrind; our $opt_valgrind;
our $opt_valgrind_mysqld;
our $opt_valgrind_mysqltest; our $opt_valgrind_mysqltest;
our $opt_valgrind_all; our $opt_valgrind_all;
our $opt_valgrind_options; our $opt_valgrind_options;
...@@ -509,6 +514,9 @@ sub command_line_setup () { ...@@ -509,6 +514,9 @@ sub command_line_setup () {
# Control what engine/variation to run # Control what engine/variation to run
'embedded-server' => \$opt_embedded_server, 'embedded-server' => \$opt_embedded_server,
'ps-protocol' => \$opt_ps_protocol, 'ps-protocol' => \$opt_ps_protocol,
'sp-protocol' => \$opt_sp_protocol,
'view-protocol' => \$opt_view_protocol,
'cursor-protocol' => \$opt_cursor_protocol,
'ssl|with-openssl' => \$opt_ssl, 'ssl|with-openssl' => \$opt_ssl,
'skip-ssl' => \$opt_skip_ssl, 'skip-ssl' => \$opt_skip_ssl,
'compress' => \$opt_compress, 'compress' => \$opt_compress,
...@@ -762,6 +770,7 @@ sub command_line_setup () { ...@@ -762,6 +770,7 @@ sub command_line_setup () {
# "somestring" option is name/path of valgrind executable # "somestring" option is name/path of valgrind executable
# Take executable path from any of them, if any # Take executable path from any of them, if any
$opt_valgrind_mysqld= $opt_valgrind;
$opt_valgrind= $opt_valgrind_mysqltest if $opt_valgrind_mysqltest; $opt_valgrind= $opt_valgrind_mysqltest if $opt_valgrind_mysqltest;
$opt_valgrind= $opt_valgrind_all if $opt_valgrind_all; $opt_valgrind= $opt_valgrind_all if $opt_valgrind_all;
...@@ -911,6 +920,7 @@ sub command_line_setup () { ...@@ -911,6 +920,7 @@ sub command_line_setup () {
} }
$path_timefile= "$opt_vardir/log/mysqltest-time"; $path_timefile= "$opt_vardir/log/mysqltest-time";
$path_mysqltest_log= "$opt_vardir/log/mysqltest.log";
} }
...@@ -954,8 +964,20 @@ sub executable_setup () { ...@@ -954,8 +964,20 @@ sub executable_setup () {
"/usr/bin/false"); "/usr/bin/false");
} }
else else
{
if ( $opt_valgrind_mysqltest )
{
# client/mysqltest might be a libtool .sh script, so look for real exe
# to avoid valgrinding bash ;)
$exe_mysqltest=
mtr_exe_exists("$path_client_bindir/.libs/lt-mysqltest",
"$path_client_bindir/.libs/mysqltest",
"$path_client_bindir/mysqltest");
}
else
{ {
$exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest"); $exe_mysqltest= mtr_exe_exists("$path_client_bindir/mysqltest");
}
$exe_mysql_client_test= $exe_mysql_client_test=
mtr_exe_exists("$glob_basedir/tests/mysql_client_test", mtr_exe_exists("$glob_basedir/tests/mysql_client_test",
"/usr/bin/false"); "/usr/bin/false");
...@@ -1886,6 +1908,11 @@ sub run_testcase ($) { ...@@ -1886,6 +1908,11 @@ sub run_testcase ($) {
} }
report_failure_and_restart($tinfo); report_failure_and_restart($tinfo);
} }
# Save info from this testcase run to mysqltest.log
mtr_tofile($path_mysqltest_log,"CURRENT TEST $tname\n");
my $testcase_log= mtr_fromfile($path_timefile);
mtr_tofile($path_mysqltest_log,
$testcase_log);
} }
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
...@@ -2046,7 +2073,7 @@ sub mysqld_arguments ($$$$$) { ...@@ -2046,7 +2073,7 @@ sub mysqld_arguments ($$$$$) {
mtr_add_arg($args, "%s--language=%s", $prefix, $path_language); mtr_add_arg($args, "%s--language=%s", $prefix, $path_language);
mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix); mtr_add_arg($args, "%s--tmpdir=$opt_tmpdir", $prefix);
if ( defined $opt_valgrind ) if ( defined $opt_valgrind_mysqld )
{ {
mtr_add_arg($args, "%s--skip-safemalloc", $prefix); mtr_add_arg($args, "%s--skip-safemalloc", $prefix);
mtr_add_arg($args, "%s--skip-bdb", $prefix); mtr_add_arg($args, "%s--skip-bdb", $prefix);
...@@ -2272,7 +2299,7 @@ sub mysqld_start ($$$$) { ...@@ -2272,7 +2299,7 @@ sub mysqld_start ($$$$) {
mtr_init_args(\$args); mtr_init_args(\$args);
if ( defined $opt_valgrind ) if ( defined $opt_valgrind_mysqld )
{ {
valgrind_arguments($args, \$exe); valgrind_arguments($args, \$exe);
} }
...@@ -2603,6 +2630,21 @@ sub run_mysqltest ($) { ...@@ -2603,6 +2630,21 @@ sub run_mysqltest ($) {
mtr_add_arg($args, "--ps-protocol"); mtr_add_arg($args, "--ps-protocol");
} }
if ( $opt_sp_protocol )
{
mtr_add_arg($args, "--sp-protocol");
}
if ( $opt_view_protocol )
{
mtr_add_arg($args, "--view-protocol");
}
if ( $opt_cursor_protocol )
{
mtr_add_arg($args, "--cursor-protocol");
}
if ( $opt_strace_client ) if ( $opt_strace_client )
{ {
$exe= "strace"; # FIXME there are ktrace, .... $exe= "strace"; # FIXME there are ktrace, ....
...@@ -2711,6 +2753,7 @@ sub valgrind_arguments { ...@@ -2711,6 +2753,7 @@ sub valgrind_arguments {
mtr_add_arg($args, split(' ', $opt_valgrind_options)); mtr_add_arg($args, split(' ', $opt_valgrind_options));
} }
mtr_add_arg($args, $$exe); mtr_add_arg($args, $$exe);
$$exe= $opt_valgrind || "valgrind"; $$exe= $opt_valgrind || "valgrind";
...@@ -2734,6 +2777,10 @@ Options to control what engine/variation to run ...@@ -2734,6 +2777,10 @@ Options to control what engine/variation to run
embedded-server Use the embedded server, i.e. no mysqld daemons embedded-server Use the embedded server, i.e. no mysqld daemons
ps-protocol Use the binary protocol between client and server ps-protocol Use the binary protocol between client and server
cursor-protocol Use the cursor protocol between client and server
(implies --ps-protocol)
view-protocol Create a view to execute all non updating queries
sp-protocol Create a stored procedure to execute all queries
compress Use the compressed protocol between client and server compress Use the compressed protocol between client and server
ssl Use ssl protocol between client and server ssl Use ssl protocol between client and server
skip-ssl Dont start sterver with support for ssl connections skip-ssl Dont start sterver with support for ssl connections
...@@ -2786,9 +2833,8 @@ Options for coverage, profiling etc ...@@ -2786,9 +2833,8 @@ Options for coverage, profiling etc
gcov FIXME gcov FIXME
gprof FIXME gprof FIXME
valgrind[=EXE] Run the "mysqltest" executable as well as the "mysqld" valgrind[=EXE] Run the "mysqld" server using valgrind, optionally
server using valgrind, optionally specifying the specifying the executable path/name
executable path/name
valgrind-mysqltest[=EXE] In addition, run the "mysqltest" executable with valgrind valgrind-mysqltest[=EXE] In addition, run the "mysqltest" executable with valgrind
valgrind-all[=EXE] Adds verbose flag, and --show-reachable to valgrind valgrind-all[=EXE] Adds verbose flag, and --show-reachable to valgrind
valgrind-options=ARGS Extra options to give valgrind valgrind-options=ARGS Extra options to give valgrind
......
...@@ -110,6 +110,20 @@ wait_for_pid() ...@@ -110,6 +110,20 @@ wait_for_pid()
#$WAIT_PID pid $SLEEP_TIME_FOR_DELETE #$WAIT_PID pid $SLEEP_TIME_FOR_DELETE
} }
# Check that valgrind is installed
find_valgrind()
{
FIND_VALGRIND=`which valgrind` # this will print an error if not found
# Give good warning to the user and stop
if [ -z "$FIND_VALGRIND" ] ; then
$ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org ."
exit 1
fi
# >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr
valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && FIND_VALGRIND="$FIND_VALGRIND --tool=memcheck"
FIND_VALGRIND="$FIND_VALGRIND --alignment=8 --leak-check=yes --num-callers=16 --suppressions=$CWD/valgrind.supp"
}
# No paths below as we can't be sure where the program is! # No paths below as we can't be sure where the program is!
SED=sed SED=sed
...@@ -255,7 +269,6 @@ DO_GDB="" ...@@ -255,7 +269,6 @@ DO_GDB=""
MANUAL_GDB="" MANUAL_GDB=""
DO_DDD="" DO_DDD=""
DO_CLIENT_GDB="" DO_CLIENT_GDB=""
DO_VALGRIND_MYSQL_TEST=""
SLEEP_TIME_AFTER_RESTART=1 SLEEP_TIME_AFTER_RESTART=1
SLEEP_TIME_FOR_DELETE=10 SLEEP_TIME_FOR_DELETE=10
SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables SLEEP_TIME_FOR_FIRST_MASTER=400 # Enough time to create innodb tables
...@@ -470,15 +483,8 @@ while test $# -gt 0; do ...@@ -470,15 +483,8 @@ while test $# -gt 0; do
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --gdb"
;; ;;
--valgrind | --valgrind-all) --valgrind | --valgrind-all)
VALGRIND=`which valgrind` # this will print an error if not found find_valgrind;
# Give good warning to the user and stop VALGRIND=$FIND_VALGRIND
if [ -z "$VALGRIND" ] ; then
$ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org ."
exit 1
fi
# >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr
valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck"
VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16 --suppressions=$CWD/valgrind.supp"
EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb"
EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb"
SLEEP_TIME_AFTER_RESTART=10 SLEEP_TIME_AFTER_RESTART=10
...@@ -493,8 +499,13 @@ while test $# -gt 0; do ...@@ -493,8 +499,13 @@ while test $# -gt 0; do
TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"` TMP=`$ECHO "$1" | $SED -e "s;--valgrind-options=;;"`
VALGRIND="$VALGRIND $TMP" VALGRIND="$VALGRIND $TMP"
;; ;;
--valgrind-mysqltest) --valgrind-mysqltest | --valgrind-mysqltest-all)
DO_VALGRIND_MYSQL_TEST=1 find_valgrind;
VALGRIND_MYSQLTEST=$FIND_VALGRIND
if test "$1" = "--valgrind-mysqltest-all"
then
VALGRIND_MYSQLTEST="$VALGRIND_MYSQLTEST -v --show-reachable=yes"
fi
;; ;;
--skip-ndbcluster | --skip-ndb) --skip-ndbcluster | --skip-ndb)
USE_NDBCLUSTER="" USE_NDBCLUSTER=""
...@@ -599,7 +610,7 @@ DASH72=`$ECHO '-------------------------------------------------------'|$CUT -c ...@@ -599,7 +610,7 @@ DASH72=`$ECHO '-------------------------------------------------------'|$CUT -c
if [ x$SOURCE_DIST = x1 ] ; then if [ x$SOURCE_DIST = x1 ] ; then
if [ "x$USE_EMBEDDED_SERVER" = "x1" ] ; then if [ "x$USE_EMBEDDED_SERVER" = "x1" ] ; then
if [ -f "$BASEDIR/libmysqld/examples/mysqltest_embedded" ] ; then if [ -f "$BASEDIR/libmysqld/examples/mysqltest_embedded" ] ; then
MYSQL_TEST="$VALGRIND $BASEDIR/libmysqld/examples/mysqltest_embedded" MYSQL_TEST="$BASEDIR/libmysqld/examples/mysqltest_embedded"
else else
echo "Fatal error: Cannot find embedded server 'mysqltest_embedded'" 1>&2 echo "Fatal error: Cannot find embedded server 'mysqltest_embedded'" 1>&2
exit 1 exit 1
...@@ -733,7 +744,7 @@ else ...@@ -733,7 +744,7 @@ else
fi fi
if [ "x$USE_EMBEDDED_SERVER" = "x1" ] ; then if [ "x$USE_EMBEDDED_SERVER" = "x1" ] ; then
if [ -f "$CLIENT_BINDIR/mysqltest_embedded" ] ; then if [ -f "$CLIENT_BINDIR/mysqltest_embedded" ] ; then
MYSQL_TEST="$VALGRIND $CLIENT_BINDIR/mysqltest_embedded" MYSQL_TEST="$CLIENT_BINDIR/mysqltest_embedded"
else else
echo "Fatal error: Cannot find embedded server 'mysqltest_embedded'" 1>&2 echo "Fatal error: Cannot find embedded server 'mysqltest_embedded'" 1>&2
exit 1 exit 1
...@@ -744,7 +755,7 @@ else ...@@ -744,7 +755,7 @@ else
MYSQL_CLIENT_TEST="$CLIENT_BINDIR/mysql_client_test_embedded" MYSQL_CLIENT_TEST="$CLIENT_BINDIR/mysql_client_test_embedded"
fi fi
else else
MYSQL_TEST="$VALGRIND_MYSQLTEST $CLIENT_BINDIR/mysqltest" MYSQL_TEST="$CLIENT_BINDIR/mysqltest"
MYSQL_CLIENT_TEST="$CLIENT_BINDIR/mysql_client_test" MYSQL_CLIENT_TEST="$CLIENT_BINDIR/mysql_client_test"
fi fi
fi fi
...@@ -759,10 +770,6 @@ then ...@@ -759,10 +770,6 @@ then
SLAVE_MYSQLD=$MYSQLD SLAVE_MYSQLD=$MYSQLD
fi fi
if [ x$DO_VALGRIND_MYSQL_TEST = x1 ] ; then
MYSQL_TEST="$VALGRIND $MYSQL_TEST"
fi
# If we should run all tests cases, we will use a local server for that # If we should run all tests cases, we will use a local server for that
if [ -z "$1" -a -z "$DO_STRESS" ] if [ -z "$1" -a -z "$DO_STRESS" ]
...@@ -819,7 +826,10 @@ if [ x$USE_TIMER = x1 ] ; then ...@@ -819,7 +826,10 @@ if [ x$USE_TIMER = x1 ] ; then
fi fi
MYSQL_TEST_BIN=$MYSQL_TEST MYSQL_TEST_BIN=$MYSQL_TEST
MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS" MYSQL_TEST="$MYSQL_TEST $MYSQL_TEST_ARGS"
# Export MYSQL_TEST variable for use from .test files
export MYSQL_TEST export MYSQL_TEST
GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client GDB_CLIENT_INIT=$MYSQL_TMP_DIR/gdbinit.client
GDB_MASTER_INIT=$MYSQL_TMP_DIR/gdbinit.master GDB_MASTER_INIT=$MYSQL_TMP_DIR/gdbinit.master
GDB_SLAVE_INIT=$MYSQL_TMP_DIR/gdbinit.slave GDB_SLAVE_INIT=$MYSQL_TMP_DIR/gdbinit.slave
...@@ -829,6 +839,7 @@ GPROF_DIR=$MYSQL_TMP_DIR/gprof ...@@ -829,6 +839,7 @@ GPROF_DIR=$MYSQL_TMP_DIR/gprof
GPROF_MASTER=$GPROF_DIR/master.gprof GPROF_MASTER=$GPROF_DIR/master.gprof
GPROF_SLAVE=$GPROF_DIR/slave.gprof GPROF_SLAVE=$GPROF_DIR/slave.gprof
TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time" TIMEFILE="$MYSQL_TEST_DIR/var/log/mysqltest-time"
MYSQLTEST_LOG="$MYSQL_TEST_DIR/var/log/mysqltest.log"
if [ -n "$DO_CLIENT_GDB" -o -n "$DO_GDB" ] ; then if [ -n "$DO_CLIENT_GDB" -o -n "$DO_GDB" ] ; then
XTERM=`which xterm` XTERM=`which xterm`
fi fi
...@@ -991,6 +1002,18 @@ report_stats () { ...@@ -991,6 +1002,18 @@ report_stats () {
echo "WARNING: Got errors/warnings while running tests. Please examine" echo "WARNING: Got errors/warnings while running tests. Please examine"
echo "$MY_LOG_DIR/warnings for details." echo "$MY_LOG_DIR/warnings for details."
fi fi
fi # USE_RUNNING_SERVER
# Check valgrind errors from mysqltest
if [ ! -z "$VALGRIND_MYSQLTEST" ]
then
if $GREP "ERROR SUMMARY" $MYSQLTEST_LOG | $GREP -v "0 errors" > /dev/null
then
$ECHO "Valgrind detected errors!"
$GREP "ERROR SUMMARY" $MYSQLTEST_LOG | $GREP -v "0 errors"
$ECHO "See $MYSQLTEST_LOG"
fi
fi fi
} }
...@@ -1770,13 +1793,17 @@ run_testcase () ...@@ -1770,13 +1793,17 @@ run_testcase ()
$RM -f r/$tname.*reject $RM -f r/$tname.*reject
mysql_test_args="-R $result_file $EXTRA_MYSQL_TEST_OPT" mysql_test_args="-R $result_file $EXTRA_MYSQL_TEST_OPT"
if [ -z "$DO_CLIENT_GDB" ] ; then if [ -z "$DO_CLIENT_GDB" ] ; then
`$MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`; `$VALGRIND_MYSQLTEST $MYSQL_TEST $mysql_test_args < $tf 2> $TIMEFILE`;
else else
do_gdb_test "$mysql_test_args" "$tf" do_gdb_test "$mysql_test_args" "$tf"
fi fi
res=$? res=$?
# Save the testcase log to mysqltest log file
echo "CURRENT_TEST: $tname" >> $MYSQLTEST_LOG
cat $TIMEFILE >> $MYSQLTEST_LOG
pname=`$ECHO "$tname "|$CUT -c 1-24` pname=`$ECHO "$tname "|$CUT -c 1-24`
RES="$pname" RES="$pname"
......
...@@ -16,7 +16,7 @@ otto ...@@ -16,7 +16,7 @@ otto
mysqltest: At line 1: query 'select otto from (select 1 as otto) as t1' succeeded - should have failed with sqlstate 42S22... 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; select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list' ERROR 42S22: Unknown column 'friedrich' in 'field list'
mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22 instead of 00000... mysqltest: At line 1: query 'select friedrich from (select 1 as otto) as t1' failed with wrong sqlstate 42S22: 'Unknown column 'friedrich' in 'field list'', instead of 00000...
select otto from (select 1 as otto) as t1; select otto from (select 1 as otto) as t1;
otto otto
1 1
...@@ -133,7 +133,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist ...@@ -133,7 +133,7 @@ ERROR 42S02: Table 'test.t1' doesn't exist
select 1146 as "after_!errno_masked_error" ; select 1146 as "after_!errno_masked_error" ;
after_!errno_masked_error after_!errno_masked_error
1146 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: 'Table 'test.t1' doesn't exist', instead of 1000...
garbage ; 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 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" ; select 1064 as "after_--enable_abort_on_error" ;
...@@ -141,7 +141,7 @@ after_--enable_abort_on_error ...@@ -141,7 +141,7 @@ after_--enable_abort_on_error
1064 1064
select 3 from t1 ; select 3 from t1 ;
ERROR 42S02: Table 'test.t1' doesn't exist 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 with wrong errno 1146: 'Table 'test.t1' doesn't exist', instead of 1064...
hello hello
hello hello
;;;;;;;; ;;;;;;;;
...@@ -149,6 +149,9 @@ hello ...@@ -149,6 +149,9 @@ hello
mysqltest: At line 1: End of line junk detected: "6" mysqltest: At line 1: End of line junk detected: "6"
mysqltest: At line 1: 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: Missing delimiter
mysqltest: End of line junk detected: "sleep 7
# Another comment
"
mysqltest: At line 1: Extra delimiter ";" found mysqltest: At line 1: Extra delimiter ";" found
mysqltest: At line 1: Extra delimiter ";" found mysqltest: At line 1: Extra delimiter ";" found
MySQL MySQL
...@@ -219,6 +222,25 @@ mysqltest: At line 1: Missing arguments to let ...@@ -219,6 +222,25 @@ mysqltest: At line 1: Missing arguments to let
mysqltest: At line 1: Missing variable name in let mysqltest: At line 1: Missing variable name in let
mysqltest: At line 1: Variable name in =hi does not start with '$' mysqltest: At line 1: Variable name in =hi does not start with '$'
mysqltest: At line 1: Missing assignment operator in let mysqltest: At line 1: Missing assignment operator in let
var1
hi 1 hi there
hi
1
hi there
var2
2
var2 again
2
2
var3 two columns with same name
1 2 3
2
2
3
mysqltest: At line 1: Missing file name in source mysqltest: At line 1: Missing file name in source
mysqltest: At line 1: Could not open file ./non_existingFile 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/recursive.sql": At line 1: Source directives are nesting too deep
...@@ -301,6 +323,7 @@ mysqltest: At line 1: End of line junk detected: "1000" ...@@ -301,6 +323,7 @@ mysqltest: At line 1: End of line junk detected: "1000"
mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: Missing arguments to system, nothing to do!
mysqltest: At line 1: Missing arguments to system, nothing to do! mysqltest: At line 1: Missing arguments to system, nothing to do!
mysqltest: At line 1: system command 'false' failed mysqltest: At line 1: system command 'false' failed
system command 'NonExistsinfComamdn 2> /dev/null' failed
test test
test2 test2
test3 test3
...@@ -328,6 +351,7 @@ mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_re ...@@ -328,6 +351,7 @@ mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_re
mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a;' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a;'
mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a'
mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a ' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a '
OK
mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a b c' mysqltest: At line 1: Wrong number of arguments to replace_result in 'replace_result a b c'
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; select "a" as col1, "c" as col2;
...@@ -350,9 +374,10 @@ mysqltest: At line 1: Missing connection user ...@@ -350,9 +374,10 @@ mysqltest: At line 1: Missing connection user
mysqltest: At line 1: Missing connection user mysqltest: At line 1: Missing connection user
mysqltest: At line 1: Missing connection password mysqltest: At line 1: Missing connection password
mysqltest: At line 1: Missing connection db mysqltest: At line 1: Missing connection db
mysqltest: At line 1: Could not open connection 'con2': Unknown database 'illegal_db' mysqltest: At line 1: Could not open connection 'con2': 1049 Unknown database 'illegal_db'
mysqltest: At line 1: Illegal argument for port: 'illegal_port' mysqltest: At line 1: Illegal argument for port: 'illegal_port'
mysqltest: At line 1: Illegal option to connect: SMTP mysqltest: At line 1: Illegal option to connect: SMTP
OK
mysqltest: In included file "./var/tmp/con.sql": At line 7: Connection limit exhausted - increase MAX_CONS in mysqltest.c mysqltest: In included file "./var/tmp/con.sql": At line 7: Connection limit exhausted - increase MAX_CONS in mysqltest.c
mysqltest: In included file "./var/tmp/con.sql": At line 3: connection 'test_con1' not found in connection pool mysqltest: In included file "./var/tmp/con.sql": At line 3: connection 'test_con1' not found in connection pool
mysqltest: In included file "./var/tmp/con.sql": At line 2: Connection test_con1 already exists mysqltest: In included file "./var/tmp/con.sql": At line 2: Connection test_con1 already exists
...@@ -391,20 +416,20 @@ root@localhost ...@@ -391,20 +416,20 @@ root@localhost
-------------------------------------------------------------------------------- --------------------------------------------------------------------------------
this will be executed this will be executed
this will be executed this will be executed
mysqltest: Result length mismatch
mysqltest: The test didn't produce any output
Failing multi statement query
mysqltest: At line 3: query 'create table t1 (a int primary key); mysqltest: At line 3: query 'create table t1 (a int primary key);
insert into t1 values (1); insert into t1 values (1);
select 'select-me'; select 'select-me';
insertz 'error query'' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz 'error query'' at line 1 insertz 'error query'' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz 'error query'' at line 1
drop table t1; drop table t1;
drop table t1; mysqltest: At line 3: query 'create table t1 (a int primary key);
create table t1 (a int primary key);
insert into t1 values (1); insert into t1 values (1);
select 'select-me'; select 'select-me';
insertz error query|||| insertz 'error query'' failed: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz 'error query'' at line 1
select-me
select-me
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz error query' at line 1
drop table t1; drop table t1;
Multi statement using expected error
create table t1 (a int primary key); create table t1 (a int primary key);
insert into t1 values (1); insert into t1 values (1);
select 'select-me'; select 'select-me';
...@@ -413,3 +438,4 @@ select-me ...@@ -413,3 +438,4 @@ select-me
select-me select-me
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz error query' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz error query' at line 1
drop table t1; drop table t1;
drop table t1;
...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
......
...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
......
...@@ -86,6 +86,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -86,6 +86,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
......
...@@ -128,6 +128,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -128,6 +128,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
...@@ -3140,6 +3142,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -3140,6 +3142,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
......
...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
......
...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c ...@@ -85,6 +85,8 @@ c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 c16 c17 c18 c19 c20 c21 c22 c
1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday 1 1 1 1 1 1 1 1 1 1 1.0000 1.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 1 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext one monday
9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday 9 9 9 9 9 9 9 9 9 9 9.0000 9.0000 2004-02-29 2004-02-29 11:11:11 2004-02-29 11:11:11 11:11:11 2004 1 0 a 123456789a 123456789a123456789b123456789c tinyblob tinytext blob text mediumblob mediumtext longblob longtext two tuesday
set @arg00='SELECT' ; set @arg00='SELECT' ;
@arg00 a from t1 where a=1;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@arg00 a from t1 where a=1' at line 1
prepare stmt1 from ' ? a from t1 where a=1 '; prepare stmt1 from ' ? a from t1 where a=1 ';
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1 ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '? a from t1 where a=1' at line 1
set @arg00=1 ; set @arg00=1 ;
......
...@@ -61,9 +61,7 @@ INSERT INTO t1 VALUES (3359361,406,3359361,'Mustermann Musterfrau',7001,'2000-05 ...@@ -61,9 +61,7 @@ INSERT INTO t1 VALUES (3359361,406,3359361,'Mustermann Musterfrau',7001,'2000-05
INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','',''); INSERT INTO t1 VALUES (3359362,406,3359362,'Mustermann Musterfrau',7001,'2000-05-20','workflow','Auftrag erledigt','Originalvertrag eingegangen und geprft','','privat',1509984,2145874,'+','','P',1909154,'MobilComSuper92000D1(Akquise)',NULL,NULL,'MS9ND1',327,24,'MobilCom Intern',7003,NULL,'auto',20010202105916,'Mobilfunk','PP','','','');
# This died because we used the field Kundentyp twice # This died because we used the field Kundentyp twice
--disable_ps_protocol
SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie; SELECT ELT(FIELD(kundentyp,'PP','PPA','PG','PGA','FK','FKA','FP','FPA','K','KA','V','VA',''), 'Privat (Private Nutzung)','Privat (Private Nutzung) Sitz im Ausland','Privat (geschaeftliche Nutzung)','Privat (geschaeftliche Nutzung) Sitz im Ausland','Firma (Kapitalgesellschaft)','Firma (Kapitalgesellschaft) Sitz im Ausland','Firma (Personengesellschaft)','Firma (Personengesellschaft) Sitz im Ausland','oeff. rechtl. Koerperschaft','oeff. rechtl. Koerperschaft Sitz im Ausland','Eingetragener Verein','Eingetragener Verein Sitz im Ausland','Typ unbekannt') AS Kundentyp ,kategorie FROM t1 WHERE hdl_nr < 2000000 AND kategorie IN ('Prepaid','Mobilfunk') AND st_klasse = 'Workflow' GROUP BY kundentyp ORDER BY kategorie;
--enable_ps_protocol
drop table t1; drop table t1;
......
...@@ -596,9 +596,7 @@ drop table t1; ...@@ -596,9 +596,7 @@ drop table t1;
CREATE TABLE t1 (n int); CREATE TABLE t1 (n int);
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
--disable_ps_protocol
SELECT n+1 AS n FROM t1 GROUP BY n; SELECT n+1 AS n FROM t1 GROUP BY n;
--enable_ps_protocol
DROP TABLE t1; DROP TABLE t1;
# #
...@@ -623,11 +621,9 @@ insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2'); ...@@ -623,11 +621,9 @@ insert into t1 values ('aaa', 'bb1'), ('aaa', 'bb2');
insert into t2 values ('aaa', 'bb1'), ('aaa', 'bb2'); insert into t2 values ('aaa', 'bb1'), ('aaa', 'bb2');
# query with ambiguous column reference 'c2' # query with ambiguous column reference 'c2'
--disable_ps_protocol
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4 select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
group by c2; group by c2;
show warnings; show warnings;
--enable_ps_protocol
# this query has no ambiguity # this query has no ambiguity
select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4 select t1.c1 as c2 from t1, t2 where t1.c2 = t2.c4
......
...@@ -7,3 +7,4 @@ ...@@ -7,3 +7,4 @@
# #
# End of 4.1 tests # End of 4.1 tests
echo ok;
...@@ -10,3 +10,5 @@ ...@@ -10,3 +10,5 @@
--exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M --exec $MYSQL_CLIENT_TEST --getopt-ll-test=25600M
# End of 4.1 tests # End of 4.1 tests
echo ok;
...@@ -364,6 +364,15 @@ select 3 from t1 ; ...@@ -364,6 +364,15 @@ select 3 from t1 ;
--error 1 --error 1
--exec $MYSQL_TEST < var/tmp/mysqltest.sql 2>&1 --exec $MYSQL_TEST < var/tmp/mysqltest.sql 2>&1
#
# Missing delimiter until eof
# The comment will be "sucked into" the sleep command since
# delimiter is missing
--system echo "sleep 7" > var/tmp/mysqltest.sql
--system echo "# Another comment" >> var/tmp/mysqltest.sql
--error 1
--exec $MYSQL_TEST < var/tmp/mysqltest.sql 2>&1
# #
# Extra delimiter # Extra delimiter
# #
...@@ -530,6 +539,42 @@ echo $novar1; ...@@ -530,6 +539,42 @@ echo $novar1;
--error 1 --error 1
--exec echo "let hi;" | $MYSQL_TEST 2>&1 --exec echo "let hi;" | $MYSQL_TEST 2>&1
# ----------------------------------------------------------------------------
# Test to assign let from query
# let $<var_name>=`<query>`;
# ----------------------------------------------------------------------------
echo var1;
let $var1= `select "hi" as "Col", 1 as "Column1", "hi there" as Col3`;
echo $var1;
echo $var1_Col;
echo $var1_Column1;
echo $var1_Col3;
echo var2;
let $var2= `select 2 as "Column num 2"`;
echo $var2;
echo $var2_Column num 2;
echo $var2_Column;
echo var2 again;
let $var2= `select 2 as "Column num 2"`;
echo $var2;
echo $var2_Column num 2;
echo $var2_Column_num_2;
echo $var2_Column;
echo var3 two columns with same name;
let $var3= `select 1 as "Col", 2 as "Col", 3 as "var3"`;
echo $var3;
echo $var3_Col;
echo $var3_Col;
echo $var3_var3;
#echo failing query in let;
#--error 1
#--exec echo "let $var2= `failing query;`" | $MYSQL_TEST 2>&1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Test source command # Test source command
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
...@@ -680,7 +725,7 @@ system echo "hej" > /dev/null; ...@@ -680,7 +725,7 @@ system echo "hej" > /dev/null;
--exec echo "system false;" | $MYSQL_TEST 2>&1 --exec echo "system false;" | $MYSQL_TEST 2>&1
--disable_abort_on_error --disable_abort_on_error
system NonExistsinfComamdn; system NonExistsinfComamdn 2> /dev/null;
--enable_abort_on_error --enable_abort_on_error
...@@ -728,20 +773,20 @@ while ($i) ...@@ -728,20 +773,20 @@ while ($i)
--error 1 --error 1
--exec echo "{;" | $MYSQL_TEST 2>&1 --exec echo "{;" | $MYSQL_TEST 2>&1
--system echo "while (0)" > var/log/mysqltest.sql --system echo "while (0)" > var/tmp/mysqltest.sql
--system echo "echo hej;" >> var/log/mysqltest.sql --system echo "echo hej;" >> var/tmp/mysqltest.sql
--error 1 --error 1
--exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 --exec $MYSQL_TEST < var/tmp/mysqltest.sql 2>&1
--system echo "while (0)" > var/log/mysqltest.sql --system echo "while (0)" > var/tmp/mysqltest.sql
--system echo "{echo hej;" >> var/log/mysqltest.sql --system echo "{echo hej;" >> var/tmp/mysqltest.sql
--error 1 --error 1
--exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 --exec $MYSQL_TEST < var/tmp/mysqltest.sql 2>&1
--system echo "while (0){" > var/log/mysqltest.sql --system echo "while (0){" > var/tmp/mysqltest.sql
--system echo "echo hej;" >> var/log/mysqltest.sql --system echo "echo hej;" >> var/tmp/mysqltest.sql
--error 1 --error 1
--exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1 --exec $MYSQL_TEST < var/tmp/mysqltest.sql 2>&1
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Test error messages returned from comments starting with a command # Test error messages returned from comments starting with a command
...@@ -769,7 +814,7 @@ select "a" as col1, "c" as col2; ...@@ -769,7 +814,7 @@ select "a" as col1, "c" as col2;
--exec echo "replace_result a;" | $MYSQL_TEST 2>&1 --exec echo "replace_result a;" | $MYSQL_TEST 2>&1
--error 1 --error 1
--exec echo "replace_result a ;" | $MYSQL_TEST 2>&1 --exec echo "replace_result a ;" | $MYSQL_TEST 2>&1
--exec echo "replace_result a b;" | $MYSQL_TEST 2>&1 --exec echo "replace_result a b; echo OK;" | $MYSQL_TEST 2>&1
--error 1 --error 1
--exec echo "--replace_result a b c" | $MYSQL_TEST 2>&1 --exec echo "--replace_result a b c" | $MYSQL_TEST 2>&1
--error 1 --error 1
...@@ -839,7 +884,7 @@ select "a" as col1, "c" as col2; ...@@ -839,7 +884,7 @@ select "a" as col1, "c" as col2;
--exec echo " disconnect test_con1; " >> var/tmp/con.sql --exec echo " disconnect test_con1; " >> var/tmp/con.sql
--exec echo " dec \$i; " >> var/tmp/con.sql --exec echo " dec \$i; " >> var/tmp/con.sql
--exec echo "}" >> var/tmp/con.sql --exec echo "}" >> var/tmp/con.sql
--exec echo "source var/tmp/con.sql;" | $MYSQL_TEST 2>&1 --exec echo "source var/tmp/con.sql; echo OK;" | $MYSQL_TEST 2>&1
# Repeat connect/disconnect, exceed max number of connections # Repeat connect/disconnect, exceed max number of connections
--exec echo "let \$i=200;" > var/tmp/con.sql --exec echo "let \$i=200;" > var/tmp/con.sql
...@@ -946,13 +991,36 @@ select "this will not be executed"; ...@@ -946,13 +991,36 @@ select "this will not be executed";
select "this will be executed"; select "this will be executed";
--enable_query_log --enable_query_log
#
# Test zero length result file. Should not pass
#
--exec touch $MYSQL_TEST_DIR/var/tmp/zero_length_file.result
--exec echo "echo ok;" > $MYSQL_TEST_DIR/var/tmp/query.sql
--error 1
--exec $MYSQL_TEST -x var/tmp/query.sql -R var/tmp/zero_length_file.result 2>&1
#
# Test that a test file that does not generate any output fails.
#
--exec echo "let \$i= 1;" > $MYSQL_TEST_DIR/var/tmp/query.sql
--error 1
--exec $MYSQL_TEST -x var/tmp/query.sql 2>&1
#
# Test that mysqltest fails when there are no queries executed
# but a result file exist
# NOTE! This will never happen as long as it's not allowed to have
# test files that does not produce any output
#--exec echo "something" > $MYSQL_TEST_DIR/var/tmp/result_file.result
#--exec echo "let \$i= 1;" > $MYSQL_TEST_DIR/var/tmp/query.sql
#--error 1
#--exec $MYSQL_TEST -x var/tmp/query.sql -R var/tmp/result_file.result 2>&1
# #
# Bug #11731 mysqltest in multi-statement queries ignores errors in # Bug #11731 mysqltest in multi-statement queries ignores errors in
# non-1st queries # non-1st queries
# #
# Failing multi statement query echo Failing multi statement query;
# PS does not support multi statement # PS does not support multi statement
--exec echo "--disable_ps_protocol" > var/tmp/bug11731.sql --exec echo "--disable_ps_protocol" > var/tmp/bug11731.sql
--exec echo "delimiter ||||;" >> var/tmp/bug11731.sql --exec echo "delimiter ||||;" >> var/tmp/bug11731.sql
...@@ -967,14 +1035,13 @@ select "this will be executed"; ...@@ -967,14 +1035,13 @@ select "this will be executed";
drop table t1; drop table t1;
--error 1 --error 1
--exec $MYSQL_TEST --record -x $MYSQL_TEST_DIR/var/tmp/bug11731.sql -R $MYSQL_TEST_DIR/var/tmp/bug11731.out --exec $MYSQL_TEST --record -x $MYSQL_TEST_DIR/var/tmp/bug11731.sql -R $MYSQL_TEST_DIR/var/tmp/bug11731.out 2>&1
# The .out file should be empty # The .out file should be non existent
--error 1 --exec test ! -e $MYSQL_TEST_DIR/var/tmp/bug11731.out
--exec test -s $MYSQL_TEST_DIR/var/tmp/bug11731.out
drop table t1; drop table t1;
# Using expected error echo Multi statement using expected error;
# PS does not support multi statement # PS does not support multi statement
--exec echo "--disable_ps_protocol" > var/tmp/bug11731.sql --exec echo "--disable_ps_protocol" > var/tmp/bug11731.sql
--exec echo "delimiter ||||;" >> var/tmp/bug11731.sql --exec echo "delimiter ||||;" >> var/tmp/bug11731.sql
...@@ -989,9 +1056,9 @@ drop table t1; ...@@ -989,9 +1056,9 @@ drop table t1;
--exec $MYSQL_TEST -x $MYSQL_TEST_DIR/var/tmp/bug11731.sql 2>&1 --exec $MYSQL_TEST -x $MYSQL_TEST_DIR/var/tmp/bug11731.sql 2>&1
drop table t1; drop table t1;
--exec $MYSQL_TEST --record -x $MYSQL_TEST_DIR/var/tmp/bug11731.sql -R $MYSQL_TEST_DIR/var/tmp/bug11731.out --exec $MYSQL_TEST --record -x $MYSQL_TEST_DIR/var/tmp/bug11731.sql -R $MYSQL_TEST_DIR/var/tmp/bug11731.out 2>&1
--exec cat $MYSQL_TEST_DIR/var/tmp/bug11731.out # The .out file should exist
--exec test -s $MYSQL_TEST_DIR/var/tmp/bug11731.out
drop table t1; drop table t1;
...@@ -27,12 +27,9 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g ...@@ -27,12 +27,9 @@ select 't1',b,count(*) from t1 group by b UNION select 't2',b,count(*) from t2 g
(select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b; (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by t1.b;
explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc; explain extended (select a,b from t1 limit 2) union all (select a,b from t2 order by a limit 1) order by b desc;
(select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2; (select sql_calc_found_rows a,b from t1 limit 2) union all (select a,b from t2 order by a) limit 2;
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2; select sql_calc_found_rows a,b from t1 union all select a,b from t2 limit 2;
select found_rows(); select found_rows();
--enable_ps_protocol
# #
# Test some error conditions with UNION # Test some error conditions with UNION
...@@ -210,27 +207,15 @@ insert into t2 values (3),(4),(5); ...@@ -210,27 +207,15 @@ insert into t2 values (3),(4),(5);
# Test global limits # Test global limits
(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2) LIMIT 1; (SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2) LIMIT 1;
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
--enable_ps_protocol
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2) LIMIT 2; (SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2) LIMIT 2;
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
--enable_ps_protocol
# Test cases where found_rows() should return number of returned rows # Test cases where found_rows() should return number of returned rows
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2); (SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION all (SELECT * FROM t2);
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
--enable_ps_protocol
(SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2 LIMIT 1); (SELECT SQL_CALC_FOUND_ROWS * FROM t1) UNION all (SELECT * FROM t2 LIMIT 1);
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
--enable_ps_protocol
# This used to work in 4.0 but not anymore in 4.1 # This used to work in 4.0 but not anymore in 4.1
--error 1064 --error 1064
(SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2 LIMIT 1; (SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1) UNION SELECT * FROM t2 LIMIT 1;
...@@ -238,15 +223,9 @@ select found_rows(); ...@@ -238,15 +223,9 @@ select found_rows();
# In these case found_rows() should work # In these case found_rows() should work
SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 LIMIT 1 UNION all SELECT * FROM t2 LIMIT 2;
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
--disable_ps_protocol
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION all SELECT * FROM t2 LIMIT 2;
# PS doesn't work correctly with found_rows: to be fixed
--disable_ps_protocol
select found_rows(); select found_rows();
--disable_ps_protocol
# The following examples will not be exact # The following examples will not be exact
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2; SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 2;
......
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