diff options
author | monty@donna.mysql.com <> | 2000-12-27 03:31:06 +0200 |
---|---|---|
committer | monty@donna.mysql.com <> | 2000-12-27 03:31:06 +0200 |
commit | 361067e9150f7fa57d5b2ac722ed55df9c14cc53 (patch) | |
tree | 98ed8596cd2fca2adf236423b157ecc4e296bce2 /client | |
parent | 988a98c39315c53d47e28b79ef88f0a0b7ac4287 (diff) | |
download | mariadb-git-361067e9150f7fa57d5b2ac722ed55df9c14cc53.tar.gz |
Extended mysqltest with --commands and 'require'
Fixed test results.
Added mysqld variable 'have_isam'
Diffstat (limited to 'client')
-rw-r--r-- | client/mysqltest.c | 938 |
1 files changed, 482 insertions, 456 deletions
diff --git a/client/mysqltest.c b/client/mysqltest.c index 98ef9c99399..c3f5d4b0bcf 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -23,7 +23,7 @@ * **/ -#define MTEST_VERSION "1.0" +#define MTEST_VERSION "1.1" #include "global.h" #include "my_sys.h" @@ -42,12 +42,12 @@ #include <errno.h> #define MAX_QUERY 16384 -#define PAD_SIZE 128 +#define PAD_SIZE 128 #define MAX_CONS 1024 #define MAX_INCLUDE_DEPTH 16 #define LAZY_GUESS_BUF_SIZE 8192 -#define INIT_Q_LINES 1024 -#define MIN_VAR_ALLOC 32 +#define INIT_Q_LINES 1024 +#define MIN_VAR_ALLOC 32 #define BLOCK_STACK_DEPTH 32 int record = 0, verbose = 0, silent = 0; @@ -100,21 +100,31 @@ VAR var_reg[10]; struct connection cons[MAX_CONS]; struct connection* cur_con, *next_con, *cons_end; -/* this should really be called command*/ +/* this should really be called command */ struct query { char q[MAX_QUERY]; - int has_result_set; int first_word_len; - int abort_on_error; + my_bool abort_on_error, require_file; uint expected_errno; char record_file[FN_REFLEN]; - enum {Q_CONNECTION, Q_QUERY, Q_CONNECT, - Q_SLEEP, Q_INC, Q_DEC,Q_SOURCE, - Q_DISCONNECT,Q_LET, Q_ECHO, Q_WHILE, Q_END_BLOCK, - Q_SYSTEM, Q_UNKNOWN} type; + /* Add new commands before Q_UNKNOWN */ + enum { Q_CONNECTION=1, Q_QUERY, Q_CONNECT, + Q_SLEEP, Q_INC, Q_DEC,Q_SOURCE, + Q_DISCONNECT,Q_LET, Q_ECHO, Q_WHILE, Q_END_BLOCK, + Q_SYSTEM, Q_RESULT, Q_REQUIRE, + Q_UNKNOWN, Q_COMMENT, Q_COMMENT_WITH_COMMAND} type; }; +const char *command_names[] = { +"connection", "query","connect","sleep","inc","dec","source","disconnect", +"let","echo","while","end","system","result", "require",0 +}; + +TYPELIB command_typelib= {array_elements(command_names),"", + command_names}; + + #define DS_CHUNK 16384 typedef struct dyn_string @@ -131,11 +141,53 @@ void dyn_string_append(DYN_STRING* ds, const char* str, int len); int dyn_string_cmp(DYN_STRING* ds, const char* fname); void reject_dump(const char* record_file, char* buf, int size); - -static void die(const char* fmt, ...); int close_connection(struct query* q); VAR* var_get(char* var_name, char* var_name_end, int raw); -void verbose_msg(const char* fmt, ...); + +static void close_cons() +{ + for(--next_con; next_con >= cons; --next_con) + { + mysql_close(&next_con->mysql); + my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); + } +} + +static void die(const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); + fprintf(stderr, "%s: ", my_progname); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); + close_cons(); + exit(1); +} + +static void abort_not_supported_test() +{ + fprintf(stderr, "This test is not supported by this installation\n"); + if (!silent) + printf("skipped\n"); + close_cons(); + exit(2); +} + +static void verbose_msg(const char* fmt, ...) +{ + va_list args; + + if (!verbose) return; + + va_start(args, fmt); + + fprintf(stderr, "%s: ", my_progname); + vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); + va_end(args); +} + void init_parser() { @@ -145,9 +197,9 @@ void init_parser() int hex_val(int c) { - if(isdigit(c)) + if (isdigit(c)) return c - '0'; - else if((c = tolower(c)) >= 'a' && c <= 'f') + else if ((c = tolower(c)) >= 'a' && c <= 'f') return c - 'a' + 10; else return -1; @@ -155,7 +207,7 @@ int hex_val(int c) void dyn_string_init(DYN_STRING* ds) { - if(!(ds->str = (char*)my_malloc(DS_CHUNK, MYF(0)))) + if (!(ds->str = (char*)my_malloc(DS_CHUNK, MYF(0)))) die("Out of memory"); ds->len = 0; ds->max_len = DS_CHUNK; @@ -170,14 +222,14 @@ void dyn_string_end(DYN_STRING* ds) void dyn_string_append(DYN_STRING* ds, const char* str, int len) { int new_len; - if(!len) + if (!len) len = strlen(str); new_len = ds->len + len; - if(new_len > ds->max_len) + if (new_len > ds->max_len) { int new_alloc_len = (new_len & ~(DS_CHUNK-1)) + DS_CHUNK; char* tmp = (char*) my_malloc(new_alloc_len, MYF(0)); - if(!tmp) + if (!tmp) die("Out of memory"); memcpy(tmp, ds->str, ds->len); memcpy(tmp + ds->len, str, len); @@ -192,21 +244,23 @@ void dyn_string_append(DYN_STRING* ds, const char* str, int len) ds->len += len; } } + + int dyn_string_cmp(DYN_STRING* ds, const char* fname) { MY_STAT stat_info; char *tmp; int res; int fd; - if(!my_stat(fname, &stat_info, MYF(MY_WME))) + if (!my_stat(fname, &stat_info, MYF(MY_WME))) die("Could not stat %s: errno =%d", fname, errno); - if(stat_info.st_size != ds->len) + if (stat_info.st_size != ds->len) return 2; - if(!(tmp = (char*) my_malloc(ds->len, MYF(0)))) + if (!(tmp = (char*) my_malloc(ds->len, MYF(0)))) die("Out of memory"); - if((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) + if ((fd = my_open(fname, O_RDONLY, MYF(MY_WME))) < 0) die("Could not open %s: errno = %d", fname, errno); - if(my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP))) + if (my_read(fd, (byte*)tmp, stat_info.st_size, MYF(MY_WME|MY_NABP))) die("read failed"); res = (memcmp(tmp, ds->str, stat_info.st_size)) ? 1 : 0; my_free((gptr)tmp, MYF(0)); @@ -214,25 +268,30 @@ int dyn_string_cmp(DYN_STRING* ds, const char* fname) return res; } -int check_result(DYN_STRING* ds, const char* fname) +static int check_result(DYN_STRING* ds, const char* fname, + my_bool require_option) { int error = 0; - switch(dyn_string_cmp(ds, fname)) - { - case 0: - break; /* ok */ - case 2: - verbose_msg("Result length mismatch"); - error = 1; - break; - case 1: - verbose_msg("Result content mismatch"); - error = 1; - break; - default: /* impossible */ - die("Unknown error code from dyn_string_cmp()"); - } - if(error) + int res=dyn_string_cmp(ds, fname); + + if (res && require_option) + abort_not_supported_test(); + switch (res) + { + case 0: + break; /* ok */ + case 2: + verbose_msg("Result length mismatch"); + error = 1; + break; + case 1: + verbose_msg("Result content mismatch"); + error = 1; + break; + default: /* impossible */ + die("Unknown error code from dyn_string_cmp()"); + } + if (error) reject_dump(fname, ds->str, ds->len); return error; } @@ -241,26 +300,26 @@ VAR* var_get(char* var_name, char* var_name_end, int raw) { int digit; VAR* v; - if(*var_name++ != '$') - { - --var_name; - goto err; - } + if (*var_name++ != '$') + { + --var_name; + goto err; + } digit = *var_name - '0'; - if(!(digit < 10 && digit >= 0)) - { - --var_name; - goto err; - } + if (!(digit < 10 && digit >= 0)) + { + --var_name; + goto err; + } v = var_reg + digit; - if(!raw && v->int_dirty) - { - sprintf(v->str_val, "%d", v->int_val); - v->int_dirty = 0; - } + if (!raw && v->int_dirty) + { + sprintf(v->str_val, "%d", v->int_val); + v->int_dirty = 0; + } return v; - err: - if(var_name_end) +err: + if (var_name_end) *var_name_end = 0; die("Unsupported variable name: %s", var_name); return 0; @@ -272,23 +331,23 @@ int var_set(char* var_name, char* var_name_end, char* var_val, int digit; int val_len; VAR* v; - if(*var_name++ != '$') + if (*var_name++ != '$') { --var_name; *var_name_end = 0; die("Variable name in %s does not start with '$'", var_name); } digit = *var_name - '0'; - if(!(digit < 10 && digit >= 0)) + if (!(digit < 10 && digit >= 0)) { *var_name_end = 0; die("Unsupported variable name: %s", var_name); } v = var_reg + digit; - if(v->alloced_len < (val_len = (int)(var_val_end - var_val)+1)) + if (v->alloced_len < (val_len = (int)(var_val_end - var_val)+1)) { v->alloced_len = (val_len < MIN_VAR_ALLOC) ? MIN_VAR_ALLOC : val_len; - if(!(v->str_val = + if (!(v->str_val = v->str_val ? my_realloc(v->str_val, v->alloced_len, MYF(MY_WME)) : my_malloc(v->alloced_len, MYF(MY_WME)))) die("Out of memory"); @@ -302,9 +361,9 @@ int var_set(char* var_name, char* var_name_end, char* var_val, int open_file(const char* name) { - if(*cur_file && ++cur_file == file_stack_end) + if (*cur_file && ++cur_file == file_stack_end) die("Source directives are nesting too deep"); - if(!(*cur_file = fopen(name, "r"))) + if (!(*cur_file = my_fopen(name, O_RDONLY, MYF(MY_WME)))) die("Could not read '%s': errno %d\n", name, errno); return 0; @@ -315,7 +374,7 @@ int do_source(struct query* q) char* p, *name; p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; - if(!*p) + if (!*p) die("Missing file name in source\n"); name = p; while(*p && !isspace(*p)) @@ -329,9 +388,9 @@ int do_source(struct query* q) int eval_expr(VAR* v, char* p, char* p_end) { VAR* vp; - if(*p == '$') + if (*p == '$') { - if((vp = var_get(p,p_end,0))) + if ((vp = var_get(p,p_end,0))) { memcpy(v, vp, sizeof(VAR)); return 0; @@ -344,7 +403,7 @@ int eval_expr(VAR* v, char* p, char* p_end) return 0; } - if(p_end) + if (p_end) *p_end = 0; die("Invalid expr: %s", p); return 1; @@ -381,14 +440,14 @@ int do_system(struct query* q) p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; eval_expr(&v, p, 0); /* NULL terminated */ - if(v.str_val_len > 1) + if (v.str_val_len > 1) { char expr_buf[512]; - if((uint)v.str_val_len > sizeof(expr_buf) - 1) + if ((uint)v.str_val_len > sizeof(expr_buf) - 1) v.str_val_len = sizeof(expr_buf) - 1; memcpy(expr_buf, v.str_val, v.str_val_len); expr_buf[v.str_val_len] = 0; - if(system(expr_buf) && q->abort_on_error) + if (system(expr_buf) && q->abort_on_error) die("system command '%s' failed", expr_buf); } return 0; @@ -401,7 +460,7 @@ int do_echo(struct query* q) p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; eval_expr(&v, p, 0); /* NULL terminated */ - if(v.str_val_len > 1) + if (v.str_val_len > 1) { fflush(stdout); write(1, v.str_val, v.str_val_len - 1); @@ -415,13 +474,13 @@ int do_let(struct query* q) char* p, *var_name, *var_name_end, *var_val_start; p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; - if(!*p) + if (!*p) die("Missing variable name in let\n"); var_name = p; while(*p && (*p != '=' || isspace(*p))) p++; var_name_end = p; - if(*p == '=') p++; + if (*p == '=') p++; while(*p && isspace(*p)) p++; var_val_start = p; @@ -437,37 +496,48 @@ int do_sleep(struct query* q) int dec_mul = 1000000; p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; - if(!*p) - die("Missing agument in sleep\n"); + if (!*p) + die("Missing argument in sleep\n"); arg = p; t.tv_sec = atoi(arg); t.tv_usec = 0; while(*p && *p != '.' && !isspace(*p)) p++; - if(*p == '.') - { - char c; - char *p_end; - p++; - p_end = p + 6; + if (*p == '.') + { + char c; + char *p_end; + p++; + p_end = p + 6; - for(;p <= p_end; ++p) - { - c = *p - '0'; - if(c < 10 && c >= 0) - { - t.tv_usec = t.tv_usec * 10 + c; - dec_mul /= 10; - } - else - break; - } + for(;p <= p_end; ++p) + { + c = *p - '0'; + if (c < 10 && c >= 0) + { + t.tv_usec = t.tv_usec * 10 + c; + dec_mul /= 10; + } + else + break; } + } *p = 0; t.tv_usec *= dec_mul; return select(0,0,0,0, &t); } +static void get_file_name(char *filename, struct query* q) +{ + char *p = (char*) q->q + q->first_word_len; + while(*p && isspace(*p)) p++; + strnmov(filename, p, FN_REFLEN); + /* Remove end space */ + while (p > filename && isspace(p[-1])) + p--; + p[0]=0; +} + int select_connection(struct query* q) { @@ -475,7 +545,7 @@ int select_connection(struct query* q) struct connection *con; p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; - if(!*p) + if (!*p) die("Missing connection name in connect\n"); name = p; while(*p && !isspace(*p)) @@ -483,7 +553,7 @@ int select_connection(struct query* q) *p = 0; for(con = cons; con < next_con; con++) - if(!strcmp(con->name, name)) + if (!strcmp(con->name, name)) { cur_con = con; return 0; @@ -499,7 +569,7 @@ int close_connection(struct query* q) struct connection *con; p = (char*)q->q + q->first_word_len; while(*p && isspace(*p)) p++; - if(!*p) + if (!*p) die("Missing connection name in connect\n"); name = p; while(*p && !isspace(*p)) @@ -507,7 +577,7 @@ int close_connection(struct query* q) *p = 0; for(con = cons; con < next_con; con++) - if(!strcmp(con->name, name)) + if (!strcmp(con->name, name)) { mysql_close(&con->mysql); return 0; @@ -529,10 +599,10 @@ char* safe_get_param(char* str, char** arg, const char* msg) *arg = str; while(*str && *str != ',' && *str != ')') { - if(isspace(*str)) *str = 0; + if (isspace(*str)) *str = 0; str++; } - if(!*str) + if (!*str) die(msg); *str++ = 0; @@ -548,7 +618,7 @@ int do_connect(struct query* q) p = q->q + q->first_word_len; while(*p && isspace(*p)) p++; - if(*p != '(') + if (*p != '(') die("Syntax error in connect - expeected '(' found '%c'", *p); p++; p = safe_get_param(p, &con_name, "missing connection name"); @@ -558,17 +628,17 @@ int do_connect(struct query* q) p = safe_get_param(p, &con_db, "missing connection db"); p = safe_get_param(p, &con_port_str, "missing connection port"); p = safe_get_param(p, &con_sock, "missing connection scoket"); - if(next_con == cons_end) + if (next_con == cons_end) die("Connection limit exhausted - incread MAX_CONS in mysqltest.c"); - if(!mysql_init(&next_con->mysql)) + if (!mysql_init(&next_con->mysql)) die("Failed on mysql_init()"); - if(!mysql_real_connect(&next_con->mysql, con_host, con_user, con_pass, + if (!mysql_real_connect(&next_con->mysql, con_host, con_user, con_pass, con_db, atoi(con_port_str), con_sock, 0)) die("Could not open connection '%s': %s", con_name, mysql_error(&next_con->mysql)); - if(!(next_con->name = my_strdup(con_name, MYF(MY_WME)))) + if (!(next_con->name = my_strdup(con_name, MYF(MY_WME)))) die("Out of memory"); cur_con = next_con++; @@ -578,13 +648,13 @@ int do_connect(struct query* q) int do_done(struct query* q) { q->type = Q_END_BLOCK; - if(cur_block == block_stack) + if (cur_block == block_stack) die("Stray '}' - end of block before beginning"); - if(block_ok) + if (block_ok) parser.current_line = *--cur_block; else { - if(!--false_block_depth) + if (!--false_block_depth) block_ok = 1; ++parser.current_line; } @@ -596,22 +666,22 @@ int do_while(struct query* q) char *p = q->q + q->first_word_len; char* expr_start, *expr_end; VAR v; - if(cur_block == block_stack_end) + if (cur_block == block_stack_end) die("Nesting too deep"); - if(!block_ok) + if (!block_ok) { ++false_block_depth; return 0; } expr_start = strchr(p, '('); - if(!expr_start) + if (!expr_start) die("missing '(' in while"); expr_end = strrchr(expr_start, ')'); - if(!expr_end) + if (!expr_end) die("missing ')' in while"); eval_expr(&v, ++expr_start, --expr_end); *cur_block++ = parser.current_line++; - if(!v.int_val) + if (!v.int_val) { block_ok = 0; false_block_depth = 1; @@ -619,14 +689,6 @@ int do_while(struct query* q) return 0; } -void close_cons() -{ - for(--next_con; next_con >= cons; --next_con) - { - mysql_close(&next_con->mysql); - my_free(next_con->name, MYF(MY_ALLOW_ZERO_PTR)); - } -} int safe_copy_unescape(char* dest, char* src, int size) { @@ -642,7 +704,7 @@ int safe_copy_unescape(char* dest, char* src, int size) switch(state) { case ST_NORMAL: - if(c == '\\') + if (c == '\\') { state = ST_ESCAPED; } @@ -650,7 +712,7 @@ int safe_copy_unescape(char* dest, char* src, int size) *p_dest++ = c; break; case ST_ESCAPED: - if((val = hex_val(c)) > 0) + if ((val = hex_val(c)) > 0) { *p_dest = val; state = ST_HEX2; @@ -662,7 +724,7 @@ int safe_copy_unescape(char* dest, char* src, int size) } break; case ST_HEX2: - if((val = hex_val(c)) > 0) + if ((val = hex_val(c)) > 0) { *p_dest = (*p_dest << 4) + val; p_dest++; @@ -683,118 +745,118 @@ int safe_copy_unescape(char* dest, char* src, int size) int read_line(char* buf, int size) { int c; - char* p = buf, *buf_end = buf + size; + char* p = buf, *buf_end = buf + size-1; int no_save = 0; enum {R_NORMAL, R_Q1, R_ESC_Q_Q1, R_ESC_Q_Q2, R_ESC_SLASH_Q1, R_ESC_SLASH_Q2, R_Q2, R_COMMENT, R_LINE_START} state = R_LINE_START; - for(; p < buf_end ;) + for (; p < buf_end ;) + { + no_save = 0; + c = fgetc(*cur_file); + if (feof(*cur_file)) { - no_save = 0; - c = fgetc(*cur_file); - if(feof(*cur_file)) - { - fclose(*cur_file); + my_fclose(*cur_file,MYF(0)); - if(cur_file == file_stack) - return 1; - else - { - cur_file--; - continue; - } - } - - switch(state) - { - case R_NORMAL: - if(c == ';' || c == '{') /* '{' allows some interesting syntax - * but we don't care, as long as the - * correct sytnax gets parsed right */ - { - *p = 0; - return 0; - } - else if(c == '\'') - state = R_Q1; - else if(c == '"') - state = R_Q2; - else if(c == '\n') - state = R_LINE_START; - - break; - case R_COMMENT: - no_save = 1; - if(c == '\n') - state = R_LINE_START; - break; + if (cur_file == file_stack) + return 1; + else + { + cur_file--; + continue; + } + } - case R_LINE_START: - if(c == '#') - { - state = R_COMMENT; - no_save = 1; - } - else if(isspace(c)) - no_save = 1; - else if(c == '}') - { - *buf++ = '}'; - *buf = 0; - return 0; - } - else if(c == ';' || c == '{') - { - *p = 0; - return 0; - } - else - state = R_NORMAL; - break; + switch(state) { + case R_NORMAL: + if (c == ';' || c == '{') /* '{' allows some interesting syntax + * but we don't care, as long as the + * correct sytnax gets parsed right */ + { + *p = 0; + return 0; + } + else if (c == '\'') + state = R_Q1; + else if (c == '"') + state = R_Q2; + else if (c == '\n') + state = R_LINE_START; - case R_Q1: - if(c == '\'') - state = R_ESC_Q_Q1; - else if(c == '\\') - state = R_ESC_SLASH_Q1; - break; - case R_ESC_Q_Q1: - if(c == ';') - { - *p = 0; - return 0; - } - if(c != '\'') - state = R_NORMAL; - break; - case R_ESC_SLASH_Q1: - state = R_Q1; - break; + break; + case R_COMMENT: + if (c == '\n') + { + *p=0; + return 0; + } + break; + case R_LINE_START: + if (c == '#' || c == '-') + { + state = R_COMMENT; + } + else if (isspace(c)) + no_save = 1; + else if (c == '}') + { + *buf++ = '}'; + *buf = 0; + return 0; + } + else if (c == ';' || c == '{') + { + *p = 0; + return 0; + } + else + state = R_NORMAL; + break; - case R_Q2: - if(c == '"') - state = R_ESC_Q_Q2; - else if(c == '\\') - state = R_ESC_SLASH_Q2; - break; - case R_ESC_Q_Q2: - if(c == ';') - { - *p = 0; - return 0; - } - if(c != '"') - state = R_NORMAL; - break; - case R_ESC_SLASH_Q2: - state = R_Q2; - break; - } + case R_Q1: + if (c == '\'') + state = R_ESC_Q_Q1; + else if (c == '\\') + state = R_ESC_SLASH_Q1; + break; + case R_ESC_Q_Q1: + if (c == ';') + { + *p = 0; + return 0; + } + if (c != '\'') + state = R_NORMAL; + break; + case R_ESC_SLASH_Q1: + state = R_Q1; + break; - if(!no_save) - *p++ = c; + case R_Q2: + if (c == '"') + state = R_ESC_Q_Q2; + else if (c == '\\') + state = R_ESC_SLASH_Q2; + break; + case R_ESC_Q_Q2: + if (c == ';') + { + *p = 0; + return 0; + } + if (c != '"') + state = R_NORMAL; + break; + case R_ESC_SLASH_Q2: + state = R_Q2; + break; } + + if (!no_save) + *p++ = c; + } + *p=0; /* Always end with \0 */ return feof(*cur_file); } @@ -804,58 +866,69 @@ int read_query(struct query** q_ptr) char* p = buf,* p1 ; int c, expected_errno; struct query* q; - if(parser.current_line < parser.read_lines) - { - get_dynamic(&q_lines, (gptr)q_ptr, parser.current_line) ; - return 0; - } - if(!(*q_ptr=q=(struct query*)my_malloc(sizeof(*q), MYF(MY_WME))) + if (parser.current_line < parser.read_lines) + { + get_dynamic(&q_lines, (gptr)q_ptr, parser.current_line) ; + return 0; + } + if (!(*q_ptr=q=(struct query*)my_malloc(sizeof(*q), MYF(MY_WME))) || insert_dynamic(&q_lines, (gptr)&q) ) die("Out of memory"); q->record_file[0] = 0; + q->require_file=0; q->abort_on_error = 1; - q->has_result_set = 0; q->first_word_len = 0; q->expected_errno = 0; q->type = Q_UNKNOWN; - if(read_line(buf, sizeof(buf))) + if (read_line(buf, sizeof(buf))) return 1; - if(*p == '!') + + if (*p == '#') + { + q->type = Q_COMMENT; + } + else if (p[0] == '-' && p[1] == '-') + { + q->type = Q_COMMENT_WITH_COMMAND; + p+=2; /* To calculate first word */ + } + else + { + if (*p == '!') { - q->abort_on_error = 0; - p++; - if(*p == '$') - { - expected_errno = 0; - p++; - for(;isdigit(*p);p++) - expected_errno = expected_errno * 10 + *p - '0'; - q->expected_errno = expected_errno; - } + q->abort_on_error = 0; + p++; + if (*p == '$') + { + expected_errno = 0; + p++; + for (;isdigit(*p);p++) + expected_errno = expected_errno * 10 + *p - '0'; + q->expected_errno = expected_errno; + } } - while(*p && isspace(*p)) p++ ; - if(*p == '@') + while(*p && isspace(*p)) p++ ; + if (*p == '@') { - q->has_result_set = 1; p++; p1 = q->record_file; while(!isspace(c = *p) && p1 < q->record_file + sizeof(q->record_file) - 1) *p1++ = *p++; *p1 = 0; - } - + } while(*p && isspace(*p)) p++; + /* Calculate first word */ p1 = q->q; while(*p && !isspace(*p)) *p1++ = *p++; q->first_word_len = p1 - q->q; - strcpy(p1, p); + strmov(p1, p); parser.read_lines++; return 0; } @@ -878,31 +951,6 @@ struct option long_options[] = {0, 0,0,0} }; -void die(const char* fmt, ...) -{ - va_list args; - va_start(args, fmt); - fprintf(stderr, "%s: ", my_progname); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); - close_cons(); - exit(1); -} - -void verbose_msg(const char* fmt, ...) -{ - va_list args; - - if(!verbose) return; - - va_start(args, fmt); - - fprintf(stderr, "%s: ", my_progname); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); - va_end(args); -} static void print_version(void) { @@ -957,7 +1005,7 @@ int parse_args(int argc, char **argv) case 'R': result_file = optarg; break; - case 'p': + case 'p': if (optarg) { my_free(pass,MYF(MY_ALLOW_ZERO_PTR)); @@ -990,7 +1038,7 @@ int parse_args(int argc, char **argv) exit(0); default: usage(); - exit(0); + exit(1); } } @@ -1002,10 +1050,7 @@ int parse_args(int argc, char **argv) exit(1); } if (argc == 1) - { - my_free(db,MYF(MY_ALLOW_ZERO_PTR)); - db=my_strdup(*argv,MYF(MY_WME)); - } + db= *argv; if (tty_password) pass=get_tty_password(NullS); @@ -1024,9 +1069,9 @@ char* safe_str_append(char* buf, const char* str, int size) void str_to_file(const char* fname, char* str, int size) { int fd; - if((fd = my_open(fname, O_WRONLY|O_CREAT, MYF(MY_WME | MY_FFNF))) < 0) + if ((fd = my_open(fname, O_WRONLY|O_CREAT, MYF(MY_WME | MY_FFNF))) < 0) die("Could not open %s: errno = %d", fname, 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))) die("write failed"); my_close(fd, MYF(0)); } @@ -1042,6 +1087,7 @@ void reject_dump(const char* record_file, char* buf, int size) str_to_file(reject_file, buf, size); } + int run_query(MYSQL* mysql, struct query* q) { MYSQL_RES* res = 0; @@ -1055,66 +1101,69 @@ int run_query(MYSQL* mysql, struct query* q) DYN_STRING ds_tmp; dyn_string_init(&ds_tmp); - if( q->record_file[0]) - { - ds = &ds_tmp; - } - - + if ( q->record_file[0]) + { + ds = &ds_tmp; + } - if(mysql_query(mysql, q->q)) + if (mysql_query(mysql, q->q)) + { + if (q->require_file) + abort_not_supported_test(); + if (q->abort_on_error) + die("query '%s' failed: %s", q->q, mysql_error(mysql)); + else { - if(q->abort_on_error) - die("query '%s' failed: %s", q->q, mysql_error(mysql)); - else - { - if(q->expected_errno) - { - error = (q->expected_errno != mysql_errno(mysql)); - if(error) - verbose_msg("query '%s' failed with wrong errno\ + if (q->expected_errno) + { + error = (q->expected_errno != mysql_errno(mysql)); + if (error) + verbose_msg("query '%s' failed with wrong errno\ %d instead of %d", q->q, mysql_errno(mysql), q->expected_errno); - goto end; - } - - verbose_msg("query '%s' failed: %s", q->q, mysql_error(mysql)); - /* if we do not abort on error, failure to run the query does - not fail the whole test case - */ - goto end; - } - } + goto end; + } - if(q->expected_errno) - { - error = 1; - verbose_msg("query '%s' succeeded - should have failed with errno %d", - q->q, q->expected_errno); + verbose_msg("query '%s' failed: %s", q->q, mysql_error(mysql)); + /* if we do not abort on error, failure to run the query does + not fail the whole test case + */ goto end; } + } + + if (q->expected_errno) + { + error = 1; + verbose_msg("query '%s' succeeded - should have failed with errno %d", + q->q, q->expected_errno); + goto end; + } - if(!(res = mysql_store_result(mysql)) && mysql_field_count(mysql)) + if (!(res = mysql_store_result(mysql)) && mysql_field_count(mysql)) + { + if (q->require_file) + abort_not_supported_test(); + if (q->abort_on_error) + die("failed in mysql_store_result for query '%s'", q->q); + else { - if(q->abort_on_error) - die("failed in mysql_store_result for query '%s'", q->q); - else - { - verbose_msg("failed in mysql_store_result for query '%s'", q->q); - error = 1; - goto end; - } + verbose_msg("failed in mysql_store_result for query '%s'", q->q); + error = 1; + goto end; } + } - if(!res) goto end; + if (!res) goto end; fields = mysql_fetch_fields(res); - num_fields = mysql_num_fields(res); + num_fields = mysql_num_fields(res); for( i = 0; i < num_fields; i++) - { - dyn_string_append(ds, fields[i].name, 0); + { + if (i) dyn_string_append(ds, "\t", 1); - } + dyn_string_append(ds, fields[i].name, 0); + } dyn_string_append(ds, "\n", 1); @@ -1123,111 +1172,71 @@ int run_query(MYSQL* mysql, struct query* q) { lengths = mysql_fetch_lengths(res); for(i = 0; i < num_fields; i++) - { - val = (char*)row[i]; - len = lengths[i]; + { + val = (char*)row[i]; + len = lengths[i]; - if(!val) - { - val = (char*)"NULL"; - len = 4; - } + if (!val) + { + val = (char*)"NULL"; + len = 4; + } - dyn_string_append(ds, val, len); + if (i) dyn_string_append(ds, "\t", 1); - } + dyn_string_append(ds, val, len); + } dyn_string_append(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->len); - } - else if(q->record_file[0]) - { - error = check_result(ds, q->record_file); - } + 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->len); + } + else if (q->record_file[0]) + { + error = check_result(ds, q->record_file, q->require_file); + } - end: - if(res) mysql_free_result(res); +end: + if (res) mysql_free_result(res); return error; } -int check_first_word(struct query* q, const char* word, int len) -{ - const char* p, *p1, *end; - - if(len != q->first_word_len) - return 0; - - - p = word; - end = p + len; - p1 = q->q; - - for(; p < end; p++, p1++) - if(tolower(*p) != tolower(*p1)) - return 0; - - return 1; -} void get_query_type(struct query* q) { - if(*q->q == '}') - { - q->type = Q_END_BLOCK; - return; - } - q->type = Q_QUERY; - switch(q->first_word_len) - { - case 3: - if(check_first_word(q, "inc", 3)) - q->type = Q_INC; - else if(check_first_word(q, "dec", 3)) - q->type = Q_DEC; - else if(check_first_word(q, "let", 3)) - q->type = Q_LET; - break; - case 4: - if(check_first_word(q, "echo", 4)) - q->type = Q_ECHO; - break; - case 5: - if(check_first_word(q, "sleep", 5)) - q->type = Q_SLEEP; - else if(check_first_word(q, "while", 5)) - q->type = Q_WHILE; - break; - case 6: - if(check_first_word(q, "source", 6)) - q->type = Q_SOURCE; - else if(check_first_word(q, "system", 6)) - q->type = Q_SYSTEM; - break; - case 7: - if(check_first_word(q, "connect", 7)) - q->type = Q_CONNECT; - break; - case 10: - if(check_first_word(q, "connection", 10)) - q->type = Q_CONNECTION; - else if(check_first_word(q, "disconnect", 10)) - q->type = Q_DISCONNECT; - break; - - } + char save; + uint type; + if (*q->q == '}') + { + q->type = Q_END_BLOCK; + return; + } + if (q->type != Q_COMMENT_WITH_COMMAND) + q->type = Q_QUERY; + + save=q->q[q->first_word_len]; + q->q[q->first_word_len]=0; + type=find_type(q->q, &command_typelib, 0); + q->q[q->first_word_len]=save; + if (type > 0) + q->type=type; /* Found command */ } + + int main(int argc, char** argv) { int error = 0; struct query* q; + my_bool require_file=0; + char save_file[FN_REFLEN]; + save_file[0]=0; MY_INIT(argv[0]); memset(cons, 0, sizeof(cons)); @@ -1245,73 +1254,90 @@ int main(int argc, char** argv) cur_block = block_stack; dyn_string_init(&ds_res); parse_args(argc, argv); - if(!*cur_file) + if (!*cur_file) *cur_file = stdin; - - if(!( mysql_init(&cur_con->mysql))) + if (!( mysql_init(&cur_con->mysql))) die("Failed in mysql_init()"); mysql_options(&cur_con->mysql, MYSQL_READ_DEFAULT_GROUP, "mysql"); cur_con->name = my_strdup("default", MYF(MY_WME)); - if(!cur_con->name) + if (!cur_con->name) die("Out of memory"); - if(!mysql_real_connect(&cur_con->mysql, host, + if (!mysql_real_connect(&cur_con->mysql, host, user, pass, db, port, unix_sock, 0)) die("Failed in mysql_real_connect(): %s", mysql_error(&cur_con->mysql)); for(;!read_query(&q);) + { + int current_line_inc = 1, processed = 0; + if (q->type == Q_UNKNOWN || q->type == Q_COMMENT_WITH_COMMAND) + get_query_type(q); + if (block_ok) { - int current_line_inc = 1, processed = 0; - if(q->type == Q_UNKNOWN) - get_query_type(q); - if(block_ok) - { - processed = 1; - switch(q->type) - { - case Q_CONNECT: do_connect(q); break; - case Q_CONNECTION: select_connection(q); break; - case Q_DISCONNECT: close_connection(q); break; - case Q_SOURCE: do_source(q); break; - case Q_SLEEP: do_sleep(q); break; - case Q_INC: do_inc(q); break; - case Q_DEC: do_dec(q); break; - case Q_ECHO: do_echo(q); break; - case Q_SYSTEM: do_system(q); break; - case Q_LET: do_let(q); break; - case Q_QUERY: error |= run_query(&cur_con->mysql, q); break; - default: processed = 0; break; - } - } - - if(!processed) + processed = 1; + switch (q->type) { + case Q_CONNECT: do_connect(q); break; + case Q_CONNECTION: select_connection(q); break; + case Q_DISCONNECT: close_connection(q); break; + case Q_SOURCE: do_source(q); break; + case Q_SLEEP: do_sleep(q); break; + case Q_INC: do_inc(q); break; + case Q_DEC: do_dec(q); break; + case Q_ECHO: do_echo(q); break; + case Q_SYSTEM: do_system(q); break; + case Q_LET: do_let(q); break; + case Q_QUERY: + { + if (save_file[0]) { - current_line_inc = 0; - switch(q->type) - { - case Q_WHILE: do_while(q); break; - case Q_END_BLOCK: do_done(q); break; - default: current_line_inc = 1; break; - } + strmov(q->record_file,save_file); + q->require_file=require_file; + save_file[0]=0; } + error |= run_query(&cur_con->mysql, q); break; + } + case Q_RESULT: + get_file_name(save_file,q); + require_file=0; + break; + case Q_REQUIRE: + get_file_name(save_file,q); + require_file=1; + break; + case Q_COMMENT: /* Ignore row */ + case Q_COMMENT_WITH_COMMAND: + default: processed = 0; break; + } + } - parser.current_line += current_line_inc; + if (!processed) + { + current_line_inc = 0; + switch(q->type) + { + case Q_WHILE: do_while(q); break; + case Q_END_BLOCK: do_done(q); break; + default: current_line_inc = 1; break; + } } + parser.current_line += current_line_inc; + } + close_cons(); - if(result_file && ds_res.len) - { - if(!record) - error |= check_result(&ds_res, result_file); - else - str_to_file(result_file, ds_res.str, ds_res.len); - } + if (result_file && ds_res.len) + { + if(!record) + error |= check_result(&ds_res, result_file, q->require_file); + else + str_to_file(result_file, ds_res.str, ds_res.len); + } dyn_string_end(&ds_res); if (!silent) { |