Commit 7a640b44 authored by kent@mysql.com's avatar kent@mysql.com

mysqltest.c, mysqltest.result, mysqltest.test:

  Added SQLSTATE matching support to test engine
mysqltest.result, mysqltest.test:
  new file
parent 04b8a57b
......@@ -95,6 +95,38 @@ enum {OPT_MANAGER_USER=256,OPT_MANAGER_HOST,OPT_MANAGER_PASSWD,
OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA, OPT_SSL_CAPATH,
OPT_SSL_CIPHER};
/* ************************************************************************ */
/*
A line that starts with !$ or $S, and the list of error codes to
--error are stored in an internal array of structs. This struct can
hold numeric SQL error codes or SQLSTATE codes as strings. The
element next to the last active element in the list is set to type
ERR_EMPTY. When an SQL statement return an error we use this list to
check if this is an expected error.
*/
enum match_err_type
{
ERR_EMPTY= 0,
ERR_ERRNO,
ERR_SQLSTATE
};
typedef struct
{
enum match_err_type type;
union
{
uint errnum;
char sqlstate[SQLSTATE_LENGTH+1]; /* \0 terminated string */
} code;
} match_err;
static match_err global_expected_errno[MAX_EXPECTED_ERRORS];
static uint global_expected_errors;
/* ************************************************************************ */
static int record = 0, opt_sleep=0;
static char *db = 0, *pass=0;
const char* user = 0, *host = 0, *unix_sock = 0, *opt_basedir="./";
......@@ -124,7 +156,6 @@ static int *cur_block, *block_stack_end;
static int block_stack[BLOCK_STACK_DEPTH];
static int block_ok_stack[BLOCK_STACK_DEPTH];
static uint global_expected_errno[MAX_EXPECTED_ERRORS], global_expected_errors;
static CHARSET_INFO *charset_info= &my_charset_latin1;
static int embedded_server_arg_count=0;
......@@ -250,7 +281,7 @@ struct st_query
char *query, *query_buf,*first_argument,*end;
int first_word_len;
my_bool abort_on_error, require_file;
uint expected_errno[MAX_EXPECTED_ERRORS];
match_err expected_errno[MAX_EXPECTED_ERRORS];
uint expected_errors;
char record_file[FN_REFLEN];
enum enum_commands type;
......@@ -1240,24 +1271,40 @@ static void get_file_name(char *filename, struct st_query* q)
}
static uint get_ints(uint *to,struct st_query* q)
static uint get_errcodes(match_err *to,struct st_query* q)
{
char* p=q->first_argument;
long val;
uint count=0;
DBUG_ENTER("get_ints");
char* p= q->first_argument;
uint count= 0;
DBUG_ENTER("get_errcodes");
if (!*p)
die("Missing argument in %s\n", q->query);
for (; (p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val)) ; p++)
do
{
if (*p == 'S')
{
/* SQLSTATE string */
int i;
p++;
for (i = 0; my_isalnum(charset_info, *p) && i < SQLSTATE_LENGTH; p++, i++)
to[count].code.sqlstate[i]= *p;
to[count].code.sqlstate[i]= '\0';
to[count].type= ERR_SQLSTATE;
}
else
{
long val;
p=str2int(p,10,(long) INT_MIN, (long) INT_MAX, &val);
if (p == NULL)
die("Invalid argument in %s\n", q->query);
to[count].code.errnum= (uint) val;
to[count].type= ERR_ERRNO;
}
count++;
*to++= (uint) val;
if (*p != ',')
break;
}
*to++=0; /* End of data */
} while (*(p++) == ',');
to[count].type= ERR_EMPTY; /* End of data */
DBUG_RETURN(count);
}
......@@ -1850,7 +1897,6 @@ static char read_query_buf[MAX_QUERY];
int read_query(struct st_query** q_ptr)
{
char *p = read_query_buf, * p1 ;
int expected_errno;
struct st_query* q;
DBUG_ENTER("read_query");
......@@ -1900,13 +1946,25 @@ int read_query(struct st_query** q_ptr)
p++;
if (*p == '$')
{
expected_errno= 0;
p++;
for (; my_isdigit(charset_info, *p); p++)
expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0] = expected_errno;
q->expected_errno[1] = 0;
q->expected_errors=1;
int expected_errno= 0;
p++;
for (; my_isdigit(charset_info, *p); p++)
expected_errno = expected_errno * 10 + *p - '0';
q->expected_errno[0].code.errnum = expected_errno;
q->expected_errno[0].type= ERR_ERRNO;
q->expected_errno[1].type= ERR_EMPTY;
q->expected_errors=1;
}
else if (*p == 'S') /* SQLSTATE */
{
int i;
p++;
for (i = 0; my_isalnum(charset_info, *p) && i < SQLSTATE_LENGTH; p++, i++)
q->expected_errno[0].code.sqlstate[i]= *p;
q->expected_errno[0].code.sqlstate[i]= '\0';
q->expected_errno[0].type= ERR_SQLSTATE;
q->expected_errno[1].type= ERR_EMPTY;
q->expected_errors=1;
}
}
......@@ -2292,7 +2350,7 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
if (flags & QUERY_SEND)
{
got_error_on_send= mysql_send_query(mysql, query, query_len);
if (got_error_on_send && !q->expected_errno[0])
if (got_error_on_send && q->expected_errno[0].type == ERR_EMPTY)
die("At line %u: unable to send query '%s' (mysql_errno=%d , errno=%d)",
start_lineno, query, mysql_errno(mysql), errno);
}
......@@ -2324,7 +2382,10 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
{
for (i=0 ; (uint) i < q->expected_errors ; i++)
{
if ((q->expected_errno[i] == mysql_errno(mysql)))
if (((q->expected_errno[i].type == ERR_ERRNO) &&
(q->expected_errno[i].code.errnum == mysql_errno(mysql))) ||
((q->expected_errno[i].type == ERR_SQLSTATE) &&
(strcmp(q->expected_errno[i].code.sqlstate,mysql_sqlstate(mysql)) == 0)))
{
if (i == 0 && q->expected_errors == 1)
{
......@@ -2338,7 +2399,9 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
else if (q->expected_errno[0] != 0)
else if (q->expected_errno[0].type == ERR_SQLSTATE ||
(q->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
goto end; /* Ok */
}
......@@ -2354,8 +2417,12 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
dynstr_append_mem(ds,"\n",1);
if (i)
{
verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
q->query, mysql_errno(mysql), q->expected_errno[0]);
if (q->expected_errno[0].type == ERR_ERRNO)
verbose_msg("query '%s' failed with wrong errno %d instead of %d...",
q->query, mysql_errno(mysql), q->expected_errno[0].code.errnum);
else
verbose_msg("query '%s' failed with wrong sqlstate %s instead of %s...",
q->query, mysql_sqlstate(mysql), q->expected_errno[0].code.sqlstate);
error= 1;
goto end;
}
......@@ -2375,11 +2442,22 @@ int run_query(MYSQL* mysql, struct st_query* q, int flags)
}*/
}
if (q->expected_errno[0])
if (q->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0)
{
error = 1;
/* Error code we wanted was != 0, i.e. not an expected success */
verbose_msg("query '%s' succeeded - should have failed with errno %d...",
q->query, q->expected_errno[0]);
q->query, q->expected_errno[0].code.errnum);
error = 1;
goto end;
}
else if (q->expected_errno[0].type == ERR_SQLSTATE &&
strcmp(q->expected_errno[0].code.sqlstate,"00000") != 0)
{
/* SQLSTATE we wanted was != "00000", i.e. not an expected success */
verbose_msg("query '%s' succeeded - should have failed with sqlstate %s...",
q->query, q->expected_errno[0].code.sqlstate);
error = 1;
goto end;
}
......@@ -2810,7 +2888,7 @@ int main(int argc, char **argv)
require_file=0;
break;
case Q_ERROR:
global_expected_errors=get_ints(global_expected_errno,q);
global_expected_errors=get_errcodes(global_expected_errno,q);
break;
case Q_REQUIRE:
get_file_name(save_file,q);
......
select otto from (select 1 as otto) as t1;
otto
1
select otto from (select 1 as otto) as t1;
otto
1
select otto from (select 1 as otto) as t1;
otto
1
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
select otto from (select 1 as otto) as t1;
otto
1
select otto from (select 1 as otto) as t1;
otto
1
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
select friedrich from (select 1 as otto) as t1;
ERROR 42S22: Unknown column 'friedrich' in 'field list'
# ============================================================================
#
# Test of mysqltest itself
#
# ============================================================================
# ----------------------------------------------------------------------------
# Positive case(statement)
# ----------------------------------------------------------------------------
select otto from (select 1 as otto) as t1;
# expectation = response
!$0 select otto from (select 1 as otto) as t1;
--error 0
select otto from (select 1 as otto) as t1;
# expectation <> response
-- // !$1054 select otto from (select 1 as otto) as t1;
-- // --error 1054
-- // select otto from (select 1 as otto) as t1;
# ----------------------------------------------------------------------------
# Negative case(statement):
# The dervied table t1 does not contain a column named 'friedrich' .
# --> ERROR 42S22: Unknown column 'friedrich' in 'field list and
# --> 1054: Unknown column 'friedrich' in 'field list'
# ----------------------------------------------------------------------------
# expectation <> response
#!$0 select friedrich from (select 1 as otto) as t1;
#--error 0
#select friedrich from (select 1 as otto) as t1;
# expectation = response
!$1054 select friedrich from (select 1 as otto) as t1;
--error 1054
select friedrich from (select 1 as otto) as t1;
# The following unmasked unsuccessful statement must give
# 1. mysqltest gives a 'failed'
# 2. does not produce a r/<test case>.reject file !!!
# PLEASE uncomment it and check it's effect
#select friedrich from (select 1 as otto) as t1;
# ----------------------------------------------------------------------------
# Tests for the new feature - SQLSTATE error code matching
# Positive case(statement)
# ----------------------------------------------------------------------------
# expectation = response
!S00000 select otto from (select 1 as otto) as t1;
--error S00000
select otto from (select 1 as otto) as t1;
# expectation <> response
#!S42S22 select otto from (select 1 as otto) as t1;
#--error S42S22
#select otto from (select 1 as otto) as t1;
# ----------------------------------------------------------------------------
# Negative case(statement)
# ----------------------------------------------------------------------------
# expectation = response
!S42S22 select friedrich from (select 1 as otto) as t1;
--error S42S22
select friedrich from (select 1 as otto) as t1;
# expectation !=response
#!S00000 select friedrich from (select 1 as otto) as t1;
#--error S00000
#select friedrich from (select 1 as otto) as t1;
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