Commit 01b032f5 authored by unknown's avatar unknown

Merge neptunus.(none):/home/msvensson/mysql/mysql-5.0

into  neptunus.(none):/home/msvensson/mysql/wl2930/my50-wl2930


client/mysqltest.c:
  Auto merged
mysql-test/r/mysqltest.result:
  Auto merged
mysql-test/t/mysqltest.test:
  Auto merged
parents 32aaddc4 62b0ba25
...@@ -247,8 +247,6 @@ typedef struct ...@@ -247,8 +247,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 */
...@@ -436,7 +434,7 @@ static VAR* var_init(VAR* v, const char *name, int name_len, const char *val, ...@@ -436,7 +434,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); int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname);
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);
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 +461,8 @@ void free_replace(); ...@@ -463,9 +461,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 +487,10 @@ my_bool mysql_rpl_probe(MYSQL *mysql __attribute__((unused))) { return 1; } ...@@ -490,10 +487,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,8 +537,6 @@ static void do_eval(DYNAMIC_STRING* query_eval, const char *query) ...@@ -540,8 +537,6 @@ 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)
{ {
mysql_close(&next_con->mysql); mysql_close(&next_con->mysql);
...@@ -733,7 +728,21 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char *fname) ...@@ -733,7 +728,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 +754,18 @@ static int check_result(DYNAMIC_STRING* ds, const char *fname, ...@@ -745,17 +754,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 +1052,6 @@ static void do_exec(struct st_query *query) ...@@ -1042,7 +1052,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 +1078,7 @@ static void do_exec(struct st_query *query) ...@@ -1069,14 +1078,7 @@ static void do_exec(struct st_query *query)
} }
else else
{ {
if (query->record_file[0]) ds= &ds_res;
{
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds= &ds_tmp;
}
else
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,25 +1119,7 @@ static void do_exec(struct st_query *query) ...@@ -1117,25 +1119,7 @@ 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) free_replace();
{
if (glob_replace)
free_replace();
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);
}
} }
...@@ -1353,25 +1337,16 @@ int do_echo(struct st_query *q) ...@@ -1353,25 +1337,16 @@ 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]) ds= &ds_res;
{
init_dynamic_string(&ds_tmp, "", 256, 512);
ds= &ds_tmp;
}
else
ds= &ds_res;
eval_expr(&v, p, 0); /* NULL terminated */ eval_expr(&v, p, 0); /* NULL terminated */
if (v.str_val_len) if (v.str_val_len)
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 +1375,7 @@ int do_sync_with_master2(long offset) ...@@ -1400,7 +1375,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 +1392,6 @@ int do_sync_with_master2(long offset) ...@@ -1417,7 +1392,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 +1430,13 @@ int do_save_master_pos() ...@@ -1456,13 +1430,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);
...@@ -1831,7 +1805,7 @@ void free_replace() ...@@ -1831,7 +1805,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;
} }
...@@ -2056,21 +2030,11 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, ...@@ -2056,21 +2030,11 @@ 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;
/* ds= &ds_res;
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;
if (!disable_query_log) if (!disable_query_log)
{ {
...@@ -2103,13 +2067,15 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, ...@@ -2103,13 +2067,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 +2092,8 @@ int connect_n_handle_errors(struct st_query *q, MYSQL* con, const char* host, ...@@ -2126,20 +2092,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;
} }
...@@ -2564,7 +2518,7 @@ int read_line(char *buf, int size) ...@@ -2564,7 +2518,7 @@ int read_line(char *buf, int size)
state= R_Q; state= R_Q;
} }
else else
state= R_NORMAL; state= R_NORMAL;
break; break;
case R_Q: case R_Q:
...@@ -2653,7 +2607,7 @@ static char read_query_buf[MAX_QUERY]; ...@@ -2653,7 +2607,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 +2626,13 @@ int read_query(struct st_query** q_ptr) ...@@ -2672,10 +2626,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,15 +2657,6 @@ int read_query(struct st_query** q_ptr) ...@@ -2700,15 +2657,6 @@ 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:
...@@ -2956,7 +2904,17 @@ char* safe_str_append(char *buf, const char *str, int size) ...@@ -2956,7 +2904,17 @@ char* safe_str_append(char *buf, const char *str, int size)
return buf; return buf;
} }
void str_to_file(const char *fname, char *str, int size)
/*
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];
...@@ -2975,7 +2933,7 @@ void str_to_file(const char *fname, char *str, int size) ...@@ -2975,7 +2933,7 @@ void str_to_file(const char *fname, char *str, int size)
my_close(fd, MYF(0)); my_close(fd, MYF(0));
} }
void reject_dump(const char *record_file, char *buf, int size) void 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);
...@@ -3015,7 +2973,7 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) ...@@ -3015,7 +2973,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;
...@@ -3057,100 +3015,305 @@ static void append_result(DYNAMIC_STRING *ds, MYSQL_RES *res) ...@@ -3057,100 +3015,305 @@ 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;
/* /* FIXME we don't handle vertical display ..... */
Try to find out if we can run this statement using the prepared uint col_idx, row_idx;
statement protocol.
/* 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= (ulong*) my_malloc(num_fields * sizeof(ulong),
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++)
{
/* Allocate data for output */
/*
FIXME it may be a bug that for non string/blob types
'max_length' is 0, should try out 'length' in that case
*/
uint max_length= max(field[col_idx].max_length + 1, 1024);
char *str_data= (char *) my_malloc(max_length, MYF(MY_WME | MY_FAE));
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 (mysql_stmt_bind_result(stmt, bind))
die("mysql_stmt_bind_result failed: %d: %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
/* Read result from each row */
num_rows= mysql_stmt_num_rows(stmt);
for (row_idx= 0; row_idx < num_rows; row_idx++)
{
if (mysql_stmt_fetch(stmt))
die("mysql_stmt_fetch failed: %d %s",
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
/* Read result from each column */
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* FIXME is string terminated? */
const char *val= (const char *)bind[col_idx].buffer;
ulonglong len= *bind[col_idx].length;
if (col_idx < max_replace_column && replace_column[col_idx])
{
val= replace_column[col_idx];
len= strlen(val);
}
if (*bind[col_idx].is_null)
{
val= "NULL";
len= 4;
}
if (!display_result_vertically)
{
if (col_idx) /* No tab before first col */
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, (int)len);
}
else
{
dynstr_append(ds, field[col_idx].name);
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, (int)len);
dynstr_append_mem(ds, "\n", 1);
}
}
if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1);
}
if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
mysql_stmt_error(stmt), mysql_stmt_errno(stmt));
free_replace_column();
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* Free data for output */
my_free((gptr)bind[col_idx].buffer, MYF(MY_WME | MY_FAE));
}
/* Free array with bind structs, lengths and NULL flags */
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));
}
We don't have a mysql_stmt_send_execute() so we only handle
complete SEND+REAP.
If it is a '?' in the query it may be a SQL level prepared /*
statement already and we can't do it twice Append metadata for fields to output
*/ */
static void append_metadata(DYNAMIC_STRING *ds,
MYSQL_FIELD *field,
uint num_fields)
{
MYSQL_FIELD *field_end;
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t"
"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);
if (ps_protocol_enabled && disable_info && int10_to_str((int) field->flags, buff, 10);
(flags & QUERY_SEND) && (flags & QUERY_REAP) && ps_match_re(q->query)) dynstr_append(ds, buff);
return run_query_stmt(mysql, q, flags); dynstr_append_mem(ds, "\t", 1);
return run_query_normal(mysql, q, flags); 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 int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) static void append_info(DYNAMIC_STRING* ds, ulong affected_rows,
const char* info)
{ {
MYSQL_RES* res= 0; char buf[40];
uint i; sprintf(buf,"affected rows: %lu\n", affected_rows);
int error= 0, err= 0, counter= 0; dynstr_append(ds, buf);
DYNAMIC_STRING *ds; if (info)
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)
{
query = q->query;
query_len = strlen(query);
}
else
{ {
init_dynamic_string(&eval_query, "", 16384, 65536); dynstr_append(ds, "info: ");
do_eval(&eval_query, q->query); dynstr_append(ds, info);
query = eval_query.str; dynstr_append_mem(ds, "\n", 1);
query_len = eval_query.length;
} }
DBUG_PRINT("enter", ("query: '%-.60s'", query)); }
if (q->record_file[0]) /*
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++)
{ {
init_dynamic_string(&ds_tmp, "", 16384, 65536); if (col_idx)
ds = &ds_tmp; dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append(ds, field[col_idx].name);
} }
else dynstr_append_mem(ds, "\n", 1);
ds= &ds_res; }
/*
Fetch warnings from server and append to output
*/
static void append_warnings(DYNAMIC_STRING *ds, MYSQL* mysql)
{
uint count;
DBUG_ENTER("append_warnings");
if (!(count= mysql_warning_count(mysql)))
DBUG_VOID_RETURN;
/*
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));
MYSQL_RES *warn_res= mysql_store_result(mysql);
if (!warn_res)
die("Warning count is %u but didn't get any warnings",
count);
dynstr_append_mem(ds, "Warnings:\n", 10);
append_result(ds, warn_res);
mysql_free_result(warn_res);
DBUG_VOID_RETURN;
}
/*
Run query using MySQL C API
SYNPOSIS
run_query_normal
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 void run_query_normal(MYSQL *mysql, struct st_query *command,
int flags, char *query, int query_len,
DYNAMIC_STRING *ds)
{
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) if (flags & QUERY_SEND)
{ {
got_error_on_send= mysql_send_query(mysql, query, query_len); /*
if (got_error_on_send && q->expected_errno[0].type == ERR_EMPTY) Send the query, using the undocumented function mysql_send_query
die("unable to send query '%s' (mysql_errno=%d , errno=%d)", */
query, mysql_errno(mysql), errno); 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 do
{ {
if ((flags & QUERY_SEND) && !disable_query_log && !counter) /*
When on first result set, call mysql_read_query_result to retrrieve
answer to the query sent earlier
*/
if ((counter==0) && mysql_read_query_result(mysql))
{ {
replace_dynstr_append_mem(ds,query, query_len); handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
dynstr_append_mem(ds, delimiter, delimiter_length); mysql_sqlstate(mysql), ds);
dynstr_append_mem(ds, "\n", 1); goto end;
} }
if (!(flags & QUERY_REAP))
DBUG_RETURN(0);
if (got_error_on_send || /*
(!counter && (*mysql->methods->read_query_result)(mysql)) || Store the result. If res is NULL, use mysql_field_count to
(!(last_result= res= mysql_store_result(mysql)) && determine if that was expected
mysql_field_count(mysql))) */
if (!(res= mysql_store_result(mysql)) && mysql_field_count(mysql))
{ {
if (handle_error(query, q, mysql_errno(mysql), mysql_error(mysql), handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds)) mysql_sqlstate(mysql), ds);
error= 1;
goto end; goto end;
} }
...@@ -3161,27 +3324,20 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -3161,27 +3324,20 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
if (res) if (res)
{ {
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);
for (i = 0; i < num_fields; i++)
{
if (i)
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append(ds, field[i].name);
}
dynstr_append_mem(ds, "\n", 1);
}
append_result(ds, res); append_result(ds, res);
} }
/* /*
Need to call mysql_affected_rows() before the new Need to call mysql_affected_rows() before the "new"
query to find the warnings query to find the warnings
*/ */
if (!disable_info) if (!disable_info)
...@@ -3192,75 +3348,31 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -3192,75 +3348,31 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
the middle of processing results from multi-statement, because the middle of processing results from multi-statement, because
this will break protocol. this will break protocol.
*/ */
if (!disable_warnings && !mysql_more_results(mysql) && if (!disable_warnings && !mysql_more_results(mysql))
mysql_warning_count(mysql)) append_warnings(ds, 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
{
dynstr_append_mem(ds, "Warnings:\n", 10);
append_result(ds, warn_res);
mysql_free_result(warn_res);
}
}
if (!disable_info) if (!disable_info)
{ append_info(ds, affected_rows, mysql_info(mysql));
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);
}
}
} }
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);
}
if (res) if (res)
mysql_free_result(res); mysql_free_result(res);
last_result= 0;
counter++; counter++;
} while (!(err= mysql_next_result(mysql))); } while (!(err= mysql_next_result(mysql)));
if (err > 0) if (err > 0)
{ {
/* We got an error from mysql_next_result, maybe expected */ /* We got an error from mysql_next_result, maybe expected */
if (handle_error(query, q, mysql_errno(mysql), mysql_error(mysql), handle_error(query, command, mysql_errno(mysql), mysql_error(mysql),
mysql_sqlstate(mysql), ds)) mysql_sqlstate(mysql), ds);
error= 1;
goto end; 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 */ /* If we come here the query is both executed and read successfully */
if (handle_no_error(q)) handle_no_error(command);
{
error= 1;
goto end;
}
end: end:
free_replace(); free_replace();
last_result=0;
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 We save the return code (mysql_errno(mysql)) from the last call sent
...@@ -3268,12 +3380,12 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -3268,12 +3380,12 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags)
variable then can be used from the test case itself. variable then can be used from the test case itself.
*/ */
var_set_errno(mysql_errno(mysql)); var_set_errno(mysql_errno(mysql));
DBUG_RETURN(error); DBUG_VOID_RETURN;
} }
/* /*
Handle errors which occurred after execution Handle errors which occurred during execution
SYNOPSIS SYNOPSIS
handle_error() handle_error()
...@@ -3289,13 +3401,12 @@ static int run_query_normal(MYSQL* mysql, struct st_query* q, int flags) ...@@ -3289,13 +3401,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;
...@@ -3329,7 +3440,7 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3329,7 +3440,7 @@ static int handle_error(const char *query, struct st_query *q,
q->expected_errno[0].code.errnum != 0)) q->expected_errno[0].code.errnum != 0))
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;
} }
} }
...@@ -3349,7 +3460,6 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3349,7 +3460,6 @@ static int handle_error(const char *query, struct st_query *q,
else else
die("query '%s' failed with wrong sqlstate %s instead of %s...", die("query '%s' failed with wrong sqlstate %s instead of %s...",
q->query, err_sqlstate, q->expected_errno[0].code.sqlstate); q->query, err_sqlstate, q->expected_errno[0].code.sqlstate);
DBUG_RETURN(1);
} }
/* /*
...@@ -3358,7 +3468,7 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3358,7 +3468,7 @@ static int handle_error(const char *query, struct st_query *q,
*/ */
verbose_msg("query '%s' failed: %d: %s", q->query, err_errno, verbose_msg("query '%s' failed: %d: %s", q->query, err_errno,
err_error); err_error);
DBUG_RETURN(0); DBUG_VOID_RETURN;
} }
...@@ -3370,11 +3480,10 @@ static int handle_error(const char *query, struct st_query *q, ...@@ -3370,11 +3480,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");
...@@ -3384,7 +3493,6 @@ static int handle_no_error(struct st_query *q) ...@@ -3384,7 +3493,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)
...@@ -3392,111 +3500,66 @@ static int handle_no_error(struct st_query *q) ...@@ -3392,111 +3500,66 @@ 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)
{ {
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;
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 We must allocate a new stmt for each query in this program because this
may be a new connection. may be a new connection.
Well, it could be stored togeter with mysql pointer in cur_con struct
*/ */
if (!(stmt= mysql_stmt_init(mysql))) if (!(stmt= mysql_stmt_init(mysql)))
die("unable init stmt structure"); die("unable to 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);
ds= &ds_tmp;
}
else
ds= &ds_res;
/* Store the query into the output buffer if not disabled */
if (!disable_query_log)
{
replace_dynstr_append_mem(ds,query, query_len);
dynstr_append_mem(ds, delimiter, delimiter_length);
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)
run_query_stmt_handle_warnings(mysql, ds);
/* /*
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
once. A new prepare will implicitely close the old one. When we
terminate we will lose the connection, this also closes the last
prepared statement.
*/ */
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;
} }
...@@ -3507,33 +3570,24 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) ...@@ -3507,33 +3570,24 @@ 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 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);
{
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
...@@ -3541,265 +3595,145 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags) ...@@ -3541,265 +3595,145 @@ static int run_query_stmt(MYSQL *mysql, struct st_query *q, int flags)
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 (!disable_result_log)
{ {
/* Take the column count from meta info */ if ((res= mysql_stmt_result_metadata(stmt)) != NULL)
MYSQL_FIELD *field= mysql_fetch_fields(res);
uint num_fields= mysql_num_fields(res);
if (display_metadata)
run_query_display_metadata(field, num_fields, ds);
if (!display_result_vertically)
{
/* Display the table heading with the names tab separated */
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);
}
/* Now we are to put the real result into the output buffer */
/* FIXME when it works, create function append_stmt_result() */
{ {
MYSQL_BIND *bind; /* Take the column count from meta info */
my_bool *is_null; MYSQL_FIELD *fields= mysql_fetch_fields(res);
unsigned long *length; uint num_fields= mysql_num_fields(res);
/* FIXME we don't handle vertical display ..... */
uint col_idx, row_idx; if (display_metadata)
append_metadata(ds, fields, num_fields);
/* Allocate array with bind structs, lengths and NULL flags */
bind= (MYSQL_BIND*) my_malloc(num_fields * sizeof(MYSQL_BIND), if (!display_result_vertically)
MYF(MY_WME | MY_FAE | MY_ZEROFILL)); append_table_headings(ds, fields, num_fields);
length= (unsigned long*) my_malloc(num_fields * sizeof(unsigned long),
MYF(MY_WME | MY_FAE)); append_stmt_result(ds, stmt, fields, num_fields);
is_null= (my_bool*) my_malloc(num_fields * sizeof(my_bool),
MYF(MY_WME | MY_FAE)); mysql_free_result(res); /* Free normal result set with meta data */
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* Allocate data for output */
/*
FIXME it may be a bug that for non string/blob types
'max_length' is 0, should try out 'length' in that case
*/
uint max_length= max(field[col_idx].max_length + 1, 1024);
char *str_data= (char *) my_malloc(max_length, MYF(MY_WME | MY_FAE));
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++)
{
if ((err= mysql_stmt_fetch(stmt)) != 0)
die("unable to fetch all rows from statement '%s': "
"%s (mysql_stmt_errno=%d returned=%d)",
query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
/* Read result from each column */
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* FIXME is string terminated? */
const char *val= (const char *)bind[col_idx].buffer;
ulonglong len= *bind[col_idx].length;
if (col_idx < max_replace_column && replace_column[col_idx])
{
val= replace_column[col_idx];
len= strlen(val);
}
if (*bind[col_idx].is_null)
{
val= "NULL";
len= 4;
}
if (!display_result_vertically)
{
if (col_idx) /* No tab before first col */
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, (int)len);
}
else
{
dynstr_append(ds, field[col_idx].name);
dynstr_append_mem(ds, "\t", 1);
replace_dynstr_append_mem(ds, val, (int)len);
dynstr_append_mem(ds, "\n", 1);
}
}
if (!display_result_vertically)
dynstr_append_mem(ds, "\n", 1);
}
if ((err= mysql_stmt_fetch(stmt)) != MYSQL_NO_DATA)
die("fetch didn't end with MYSQL_NO_DATA from statement "
"'%s': %s (mysql_stmt_errno=%d returned=%d)",
query,
mysql_stmt_error(stmt), mysql_stmt_errno(stmt), err);
free_replace_column();
for (col_idx= 0; col_idx < num_fields; col_idx++)
{
/* Free data for output */
my_free((gptr)bind[col_idx].buffer, MYF(MY_WME | MY_FAE));
}
/* Free array with bind structs, lengths and NULL flags */
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 */ if (!disable_warnings)
run_query_stmt_handle_warnings(mysql, ds); append_warnings(ds, mysql);
if (!disable_info) if (!disable_info)
{ append_info(ds, (ulong)mysql_affected_rows(mysql), mysql_info(mysql));
char buf[40];
sprintf(buf,"affected rows: %lu\n",(ulong) mysql_affected_rows(mysql));
dynstr_append(ds, buf);
if (mysql_info(mysql))
{
dynstr_append(ds, "info: ");
dynstr_append(ds, mysql_info(mysql));
dynstr_append_mem(ds, "\n", 1);
}
}
} }
run_query_stmt_handle_warnings(mysql, ds);
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);
}
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: end:
free_replace(); free_replace();
last_result=0; /*
if (ds == &ds_tmp) We save the return code (mysql_stmt_errno(stmt)) from the last call sent
dynstr_free(&ds_tmp); to the server into the mysqltest builtin variable $mysql_errno. This
if (q->type == Q_EVAL) variable then can be used from the test case itself.
dynstr_free(&eval_query); */
var_set_errno(mysql_stmt_errno(stmt)); var_set_errno(mysql_stmt_errno(stmt));
mysql_stmt_close(stmt); mysql_stmt_close(stmt);
DBUG_RETURN(error); DBUG_VOID_RETURN;
} }
/****************************************************************************\ /*
* Broken out sub functions to run_query_stmt()
\****************************************************************************/ 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_display_metadata(MYSQL_FIELD *field, uint num_fields, static void run_query(MYSQL *mysql, struct st_query *command, int flags)
DYNAMIC_STRING *ds)
{ {
MYSQL_FIELD *field_end; DYNAMIC_STRING *ds;
dynstr_append(ds,"Catalog\tDatabase\tTable\tTable_alias\tColumn\t" DYNAMIC_STRING ds_tmp;
"Column_alias\tType\tLength\tMax length\tIs_null\t" DYNAMIC_STRING eval_query;
"Flags\tDecimals\tCharsetnr\n"); char *query;
int query_len;
for (field_end= field+num_fields ; /*
field < field_end ; Evaluate query if this is an eval command
field++) */
if (command->type == Q_EVAL)
{ {
char buff[22]; init_dynamic_string(&eval_query, "", 16384, 65536);
dynstr_append_mem(ds, field->catalog, do_eval(&eval_query, command->query);
field->catalog_length); query = eval_query.str;
dynstr_append_mem(ds, "\t", 1); query_len = eval_query.length;
dynstr_append_mem(ds, field->db, field->db_length); }
dynstr_append_mem(ds, "\t", 1); else
dynstr_append_mem(ds, field->org_table, {
field->org_table_length); query = command->query;
dynstr_append_mem(ds, "\t", 1); query_len = strlen(query);
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); When command->record_file is set the output of _this_ query
dynstr_append_mem(ds, "\t", 1); should be compared with an already existing file
int10_to_str((int) field->decimals, buff, 10); Create a temporary dynamic string to contain the output from
dynstr_append(ds, buff); this query.
dynstr_append_mem(ds, "\t", 1); */
int10_to_str((int) field->charsetnr, buff, 10); if (command->record_file[0])
dynstr_append(ds, buff); {
init_dynamic_string(&ds_tmp, "", 16384, 65536);
ds= &ds_tmp;
}
else
ds= &ds_res;
/* Store the query into the output buffer */
if (!disable_query_log && (flags & QUERY_SEND))
{
replace_dynstr_append_mem(ds,query, query_len);
dynstr_append_mem(ds, delimiter, delimiter_length);
dynstr_append_mem(ds, "\n", 1); dynstr_append_mem(ds, "\n", 1);
} }
}
/*
Find out how to run this query
static void run_query_stmt_handle_warnings(MYSQL *mysql, DYNAMIC_STRING *ds) We don't have a mysql_stmt_send_execute() so it must be a
{ complete SEND+REAP to use prepared statement
uint count;
DBUG_ENTER("run_query_stmt_handle_warnings");
if (!disable_warnings && (count= mysql_warning_count(mysql))) 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 &&
(flags & QUERY_SEND) && (flags & QUERY_REAP) &&
ps_match_re(query))
run_query_stmt(mysql, command, query, query_len, ds);
else
run_query_normal(mysql, command, flags, query, query_len, ds);
if (record)
{ {
/* /* Recording in progress */
If one day we will support execution of multi-statements if (!command->record_file[0])
through PS API we should not issue SHOW WARNINGS until die("Missing result file");
we have not read all results...
*/
DBUG_ASSERT(!mysql_more_results(mysql));
if (mysql_real_query(mysql, "SHOW WARNINGS", 13) == 0) /* Dump the output from _this_ query to the specified record_file */
{ str_to_file(command->record_file, ds->str, ds->length);
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);
append_result(ds, warn_res);
mysql_free_result(warn_res);
}
}
} }
DBUG_VOID_RETURN; else if (command->record_file[0])
{
/*
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);
}
if (ds == &ds_tmp)
dynstr_free(&ds_tmp);
if (command->type == Q_EVAL)
dynstr_free(&eval_query);
} }
...@@ -4005,7 +3939,6 @@ static void init_var_hash(MYSQL *mysql) ...@@ -4005,7 +3939,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;
...@@ -4099,7 +4032,7 @@ int main(int argc, char **argv) ...@@ -4099,7 +4032,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:
...@@ -4133,7 +4066,7 @@ int main(int argc, char **argv) ...@@ -4133,7 +4066,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);
...@@ -4160,15 +4093,6 @@ int main(int argc, char **argv) ...@@ -4160,15 +4093,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;
...@@ -4179,7 +4103,7 @@ int main(int argc, char **argv) ...@@ -4179,7 +4103,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;
...@@ -4206,7 +4130,7 @@ int main(int argc, char **argv) ...@@ -4206,7 +4130,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;
...@@ -4227,7 +4151,7 @@ int main(int argc, char **argv) ...@@ -4227,7 +4151,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;
...@@ -4349,6 +4273,12 @@ int main(int argc, char **argv) ...@@ -4349,6 +4273,12 @@ int main(int argc, char **argv)
parser.current_line += current_line_inc; parser.current_line += current_line_inc;
} }
/*
The whole test has been executed sucessfully
Time to compare result or save it to record file
The entire output from test is now kept in ds_res
*/
if (!query_executed && result_file && my_stat(result_file, &res_info, 0)) if (!query_executed && result_file && my_stat(result_file, &res_info, 0))
{ {
/* /*
...@@ -4359,39 +4289,46 @@ int main(int argc, char **argv) ...@@ -4359,39 +4289,46 @@ int main(int argc, char **argv)
no query output from the test file, e.g. regarded as no error. no query output from the test file, e.g. regarded as no error.
*/ */
if (res_info.st_size) if (res_info.st_size)
error|= (RESULT_CONTENT_MISMATCH | RESULT_LENGTH_MISMATCH); die("No queries executed but result file found!");
} }
if (ds_res.length && !error)
if (ds_res.length)
{ {
if (result_file) if (result_file)
{ {
if (!record) if (record)
error |= check_result(&ds_res, result_file, q->require_file); {
/* Dump the output from test to result file */
str_to_file(result_file, ds_res.str, ds_res.length);
}
else else
str_to_file(result_file, ds_res.str, ds_res.length); {
/* Check that the output from test is equal to result file */
check_result(&ds_res, result_file, 0);
}
} }
else else
{ {
/* Print the result to stdout */ /* No result_file to compare with, print the result to stdout */
printf("%s", ds_res.str); printf("%s", ds_res.str);
} }
} }
dynstr_free(&ds_res); else
if (!silent)
{ {
if (error) /* The test didn't produce any output */
printf("not ok\n");
else
printf("ok\n");
} }
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 */
} }
...@@ -5188,12 +5125,6 @@ static int initialize_replace_buffer(void) ...@@ -5188,12 +5125,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
*****************************************************************************/ *****************************************************************************/
......
...@@ -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
......
...@@ -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
......
...@@ -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
......
...@@ -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/log/mysqltest.sql
--system echo "# Another comment" >> var/log/mysqltest.sql
--error 1
--exec $MYSQL_TEST < var/log/mysqltest.sql 2>&1
# #
# Extra delimiter # Extra delimiter
# #
......
...@@ -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