diff options
Diffstat (limited to 'client/mysqltest.cc')
-rw-r--r-- | client/mysqltest.cc | 204 |
1 files changed, 151 insertions, 53 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 23b9eb578c6..2f12ee7f280 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -23,13 +23,6 @@ http://dev.mysql.com/doc/mysqltest/en/index.html Please keep the test framework tools identical in all versions! - - Written by: - Sasha Pachev <sasha@mysql.com> - Matt Wagner <matt@mysql.com> - Monty - Jani - Holyfoot */ #define MTEST_VERSION "3.3" @@ -129,6 +122,41 @@ static const char *load_default_groups[]= { "mysqltest", "client", "client-server", "client-mariadb", 0 }; static char line_buffer[MAX_DELIMITER_LENGTH], *line_buffer_pos= line_buffer; +/* Info on properties that can be set with --enable_X and --disable_X */ + +struct property { + my_bool *var; /* Actual variable */ + my_bool set; /* Has been set for ONE command */ + my_bool old; /* If set, thus is the old value */ + my_bool reverse; /* Varible is true if disabled */ + const char *env_name; /* Env. variable name */ +}; + +static struct property prop_list[] = { + { &abort_on_error, 0, 1, 0, "$ENABLED_ABORT_ON_ERROR" }, + { &disable_connect_log, 0, 1, 1, "$ENABLED_CONNECT_LOG" }, + { &disable_info, 0, 1, 1, "$ENABLED_INFO" }, + { &display_metadata, 0, 0, 0, "$ENABLED_METADATA" }, + { &ps_protocol_enabled, 0, 0, 0, "$ENABLED_PS_PROTOCOL" }, + { &disable_query_log, 0, 0, 1, "$ENABLED_QUERY_LOG" }, + { &disable_result_log, 0, 0, 1, "$ENABLED_RESULT_LOG" }, + { &disable_warnings, 0, 0, 1, "$ENABLED_WARNINGS" } +}; + +static my_bool once_property= FALSE; + +enum enum_prop { + P_ABORT= 0, + P_CONNECT, + P_INFO, + P_META, + P_PS, + P_QUERY, + P_RESULT, + P_WARN, + P_MAX +}; + static uint start_lineno= 0; /* Start line of current command */ static uint my_end_arg= 0; @@ -488,6 +516,7 @@ TYPELIB command_typelib= {array_elements(command_names),"", DYNAMIC_STRING ds_res; /* Points to ds_warning in run_query, so it can be freed */ DYNAMIC_STRING *ds_warn= 0; +struct st_command *curr_command= 0; char builtin_echo[FN_REFLEN]; @@ -519,6 +548,7 @@ void str_to_file(const char *fname, char *str, int size); void str_to_file2(const char *fname, char *str, int size, my_bool append); void fix_win_paths(const char *val, int len); +const char *get_errname_from_code (uint error_code); #ifdef __WIN__ void free_tmp_sh_file(); @@ -741,6 +771,7 @@ void handle_error(struct st_command*, unsigned int err_errno, const char *err_error, const char *err_sqlstate, DYNAMIC_STRING *ds); void handle_no_error(struct st_command*); +void revert_properties(); #ifdef EMBEDDED_LIBRARY @@ -1211,6 +1242,7 @@ void handle_command_error(struct st_command *command, uint error, DBUG_PRINT("info", ("command \"%.*s\" failed with expected error: %u, errno: %d", command->first_word_len, command->query, error, sys_errno)); + revert_properties(); DBUG_VOID_RETURN; } if (command->expected_errors.count > 0) @@ -1225,6 +1257,7 @@ void handle_command_error(struct st_command *command, uint error, command->first_word_len, command->query, command->expected_errors.err[0].code.errnum); } + revert_properties(); DBUG_VOID_RETURN; } @@ -2345,6 +2378,51 @@ void var_set_int(const char* name, int value) void var_set_errno(int sql_errno) { var_set_int("$mysql_errno", sql_errno); + var_set_string("$mysql_errname", get_errname_from_code(sql_errno)); +} + +/* Functions to handle --disable and --enable properties */ + +void set_once_property(enum_prop prop, my_bool val) +{ + property &pr= prop_list[prop]; + pr.set= 1; + pr.old= *pr.var; + *pr.var= val; + var_set_int(pr.env_name, (val != pr.reverse)); + once_property= TRUE; +} + +void set_property(st_command *command, enum_prop prop, my_bool val) +{ + char* p= command->first_argument; + if (p && !strcmp (p, "ONCE")) + { + command->last_argument= p + 4; + set_once_property(prop, val); + return; + } + property &pr= prop_list[prop]; + *pr.var= val; + pr.set= 0; + var_set_int(pr.env_name, (val != pr.reverse)); +} + +void revert_properties() +{ + if (! once_property) + return; + for (int i= 0; i < (int) P_MAX; i++) + { + property &pr= prop_list[i]; + if (pr.set) + { + *pr.var= pr.old; + pr.set= 0; + var_set_int(pr.env_name, (pr.old != pr.reverse)); + } + } + once_property=FALSE; } @@ -2398,9 +2476,16 @@ void var_query_set(VAR *var, const char *query, const char** query_end) init_dynamic_string(&ds_query, 0, (end - query) + 32, 256); do_eval(&ds_query, query, end, FALSE); - if (mysql_real_query(mysql, ds_query.str, ds_query.length)) - die("Error running query '%s': %d %s", ds_query.str, - mysql_errno(mysql), mysql_error(mysql)); + if (mysql_real_query(mysql, ds_query.str, ds_query.length)) + { + handle_error (curr_command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), &ds_res); + /* If error was acceptable, return empty string */ + dynstr_free(&ds_query); + eval_expr(var, "", 0); + DBUG_VOID_RETURN; + } + if (!(res= mysql_store_result(mysql))) die("Query '%s' didn't return a result set", ds_query.str); dynstr_free(&ds_query); @@ -2554,8 +2639,15 @@ void var_set_query_get_value(struct st_command *command, VAR *var) /* Run the query */ if (mysql_real_query(mysql, ds_query.str, ds_query.length)) - die("Error running query '%s': %d %s", ds_query.str, - mysql_errno(mysql), mysql_error(mysql)); + { + handle_error (curr_command, mysql_errno(mysql), mysql_error(mysql), + mysql_sqlstate(mysql), &ds_res); + /* If error was acceptable, return empty string */ + dynstr_free(&ds_query); + eval_expr(var, "", 0); + DBUG_VOID_RETURN; + } + if (!(res= mysql_store_result(mysql))) die("Query '%s' didn't return a result set", ds_query.str); @@ -4510,6 +4602,7 @@ void do_let(struct st_command *command) var_set(var_name, var_name_end, let_rhs_expr.str, (let_rhs_expr.str + let_rhs_expr.length)); dynstr_free(&let_rhs_expr); + revert_properties(); DBUG_VOID_RETURN; } @@ -4756,8 +4849,7 @@ void do_shutdown_server(struct st_command *command) } -#if MYSQL_VERSION_ID >= 50000 -/* List of error names to error codes, available from 5.0 */ +/* List of error names to error codes */ typedef struct { const char *name; @@ -4767,6 +4859,7 @@ typedef struct static st_error global_error_names[] = { + { "<No error>", -1, "" }, #include <mysqld_ername.h> { 0, 0, 0 } }; @@ -4797,16 +4890,28 @@ uint get_errcode_from_name(char *error_name, char *error_end) die("Unknown SQL error name '%s'", error_name); DBUG_RETURN(0); } -#else -uint get_errcode_from_name(char *error_name __attribute__((unused)), - char *error_end __attribute__((unused))) + +const char *get_errname_from_code (uint error_code) { - abort_not_in_this_version(); - return 0; /* Never reached */ -} -#endif + st_error *e= global_error_names; + DBUG_ENTER("get_errname_from_code"); + DBUG_PRINT("enter", ("error_code: %d", error_code)); + if (! error_code) + { + DBUG_RETURN(""); + } + for (; e->name; e++) + { + if (e->code == error_code) + { + DBUG_RETURN(e->name); + } + } + /* Apparently, errors without known names may occur */ + DBUG_RETURN("<Unknown>"); +} void do_get_errcodes(struct st_command *command) { @@ -5339,6 +5444,7 @@ do_handle_error: var_set_errno(0); handle_no_error(command); + revert_properties(); return 1; /* Connected */ } @@ -6517,7 +6623,7 @@ void print_version(void) void usage() { print_version(); - puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2010")); + puts(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000, 2011")); printf("Runs a test against the mysql server and compares output with a results file.\n\n"); printf("Usage: %s [OPTIONS] [database] < test_file\n", my_progname); my_print_help(my_long_options); @@ -7319,6 +7425,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* If we come here the query is both executed and read successfully */ handle_no_error(command); + revert_properties(); end: @@ -7452,6 +7559,7 @@ void handle_error(struct st_command *command, dynstr_append(ds,"Got one of the listed errors\n"); } /* OK */ + revert_properties(); DBUG_VOID_RETURN; } @@ -7479,6 +7587,7 @@ void handle_error(struct st_command *command, command->expected_errors.err[0].code.sqlstate); } + revert_properties(); DBUG_VOID_RETURN; } @@ -7512,7 +7621,6 @@ void handle_no_error(struct st_command *command) die("query '%s' succeeded - should have failed with sqlstate %s...", command->query, command->expected_errors.err[0].code.sqlstate); } - DBUG_VOID_RETURN; } @@ -7727,6 +7835,8 @@ end: var_set_errno(mysql_stmt_errno(stmt)); + revert_properties(); + /* Close the statement if reconnect, need new prepare */ if (mysql->reconnect) { @@ -8580,6 +8690,8 @@ int main(int argc, char **argv) { command->last_argument= command->first_argument; processed = 1; + /* Need to remember this for handle_error() */ + curr_command= command; switch (command->type) { case Q_CONNECT: do_connect(command); @@ -8591,60 +8703,46 @@ int main(int argc, char **argv) case Q_ENABLE_PREPARE_WARNINGS: prepare_warnings_enabled=1; break; case Q_DISABLE_PREPARE_WARNINGS: prepare_warnings_enabled=0; break; case Q_ENABLE_QUERY_LOG: - disable_query_log= 0; - var_set_int("$ENABLED_QUERY_LOG", 1); + set_property(command, P_QUERY, 0); break; case Q_DISABLE_QUERY_LOG: - disable_query_log= 1; - var_set_int("$ENABLED_QUERY_LOG", 0); + set_property(command, P_QUERY, 1); break; case Q_ENABLE_ABORT_ON_ERROR: - abort_on_error= 1; - var_set_int("$ENABLED_ABORT_ON_ERROR", 1); + set_property(command, P_ABORT, 1); break; case Q_DISABLE_ABORT_ON_ERROR: - abort_on_error= 0; - var_set_int("$ENABLED_ABORT_ON_ERROR", 0); + set_property(command, P_ABORT, 0); break; case Q_ENABLE_RESULT_LOG: - disable_result_log= 0; - var_set_int("$ENABLED_RESULT_LOG", 1); + set_property(command, P_RESULT, 0); break; case Q_DISABLE_RESULT_LOG: - disable_result_log=1; - var_set_int("$ENABLED_RESULT_LOG", 0); + set_property(command, P_RESULT, 1); break; case Q_ENABLE_CONNECT_LOG: - disable_connect_log=0; - var_set_int("$ENABLED_CONNECT_LOG", 1); + set_property(command, P_CONNECT, 0); break; case Q_DISABLE_CONNECT_LOG: - disable_connect_log=1; - var_set_int("$ENABLED_CONNECT_LOG", 0); + set_property(command, P_CONNECT, 1); break; case Q_ENABLE_WARNINGS: - disable_warnings= 0; - var_set_int("$ENABLED_WARNINGS", 1); + set_property(command, P_WARN, 0); break; case Q_DISABLE_WARNINGS: - disable_warnings= 1; - var_set_int("$ENABLED_WARNINGS", 0); + set_property(command, P_WARN, 1); break; case Q_ENABLE_INFO: - disable_info= 0; - var_set_int("$ENABLED_INFO", 1); + set_property(command, P_INFO, 0); break; case Q_DISABLE_INFO: - disable_info= 1; - var_set_int("$ENABLED_INFO", 0); + set_property(command, P_INFO, 1); break; case Q_ENABLE_METADATA: - display_metadata= 1; - var_set_int("$ENABLED_METADATA", 1); + set_property(command, P_META, 1); break; case Q_DISABLE_METADATA: - display_metadata= 0; - var_set_int("$ENABLED_METADATA", 0); + set_property(command, P_META, 0); break; case Q_ENABLE_COLUMN_NAMES: disable_column_names= 0; @@ -8870,12 +8968,12 @@ int main(int argc, char **argv) do_set_charset(command); break; case Q_DISABLE_PS_PROTOCOL: - ps_protocol_enabled= 0; + set_property(command, P_PS, 0); /* Close any open statements */ close_statements(); break; case Q_ENABLE_PS_PROTOCOL: - ps_protocol_enabled= ps_protocol; + set_property(command, P_PS, ps_protocol); break; case Q_DISABLE_RECONNECT: set_reconnect(cur_con->mysql, 0); |