diff options
author | unknown <monty@mysql.com/narttu.mysql.fi> | 2007-04-13 01:56:22 +0300 |
---|---|---|
committer | unknown <monty@mysql.com/narttu.mysql.fi> | 2007-04-13 01:56:22 +0300 |
commit | f3efb3dcfac96afa487709f2603784f60f021f61 (patch) | |
tree | 2eec82067ee6e913dcb025424b04b00c7e81c1cf | |
parent | 2671ba02300bf94df7d987c1e594ca2e022e9a69 (diff) | |
download | mariadb-git-f3efb3dcfac96afa487709f2603784f60f021f61.tar.gz |
Added more descriptive error message of why statement was automaticly dropped
Print information if net_clear() skipped bytes (As this otherwise hides critical timeing bugs)
Added DBUG_ASSERT if we get packets out of order
mysql_change_user() could on error send multiple packets, which caused mysql_client_test to randomly fail
include/errmsg.h:
Added more descriptive error message of why statement was automaticly dropped
libmysql/client_settings.h:
Added more descriptive error message of why statement was automaticly dropped
libmysql/errmsg.c:
Added more descriptive error message of why statement was automaticly dropped
libmysql/libmysql.c:
Added more descriptive error message of why statement was automaticly dropped
sql-common/client.c:
Added more descriptive error message of why statement was automaticly dropped
sql/net_serv.cc:
Print information if net_clear() skipped bytes (As this otherwise hides critical timeing bugs)
Added DBUG_ASSERT if we get packets out of order
sql/sql_class.cc:
We need to set killed to NOT_KILLED after cleanup() if we want to continue using THD
(If not, the connection will be closed after the current stmt)
sql/sql_parse.cc:
mysql_change_user() could on error send multiple packets, which caused mysql_client_test to randomly fail
tests/mysql_client_test.c:
More DBUG information
Better usage of --silent
Always print 'OK' the same way.
Disable test_bug17667 if run outside of mysql-test-run
-rw-r--r-- | include/errmsg.h | 3 | ||||
-rw-r--r-- | libmysql/client_settings.h | 2 | ||||
-rw-r--r-- | libmysql/errmsg.c | 3 | ||||
-rw-r--r-- | libmysql/libmysql.c | 4 | ||||
-rw-r--r-- | sql-common/client.c | 12 | ||||
-rw-r--r-- | sql/net_serv.cc | 5 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_parse.cc | 5 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 154 |
9 files changed, 114 insertions, 75 deletions
diff --git a/include/errmsg.h b/include/errmsg.h index e4d20b061a5..e7b59ca8bd7 100644 --- a/include/errmsg.h +++ b/include/errmsg.h @@ -95,6 +95,7 @@ extern const char *client_errors[]; /* Error messages */ #define CR_NO_RESULT_SET 2053 #define CR_NOT_IMPLEMENTED 2054 #define CR_SERVER_LOST_EXTENDED 2055 -#define CR_ERROR_LAST /*Copy last error nr:*/ 2055 +#define CR_STMT_CLOSED 2056 +#define CR_ERROR_LAST /*Copy last error nr:*/ 2056 /* Add error numbers before CR_ERROR_LAST and change it accordingly. */ diff --git a/libmysql/client_settings.h b/libmysql/client_settings.h index b67fbbc03af..4bc4bda5b63 100644 --- a/libmysql/client_settings.h +++ b/libmysql/client_settings.h @@ -41,7 +41,7 @@ my_bool handle_local_infile(MYSQL *mysql, const char *net_filename); void mysql_read_default_options(struct st_mysql_options *options, const char *filename,const char *group); -void mysql_detach_stmt_list(LIST **stmt_list); +void mysql_detach_stmt_list(LIST **stmt_list, const char *func_name); MYSQL * cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index 59089d5ec18..e7f495d1f43 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -83,6 +83,7 @@ const char *client_errors[]= "Attempt to read a row while there is no result set associated with the statement", "This feature is not implemented yet", "Lost connection to MySQL server at '%s', system error: %d", + "Statement closed indirectly because of a preceeding %s() call", "" }; @@ -147,6 +148,7 @@ const char *client_errors[]= "Attempt to read a row while there is no result set associated with the statement", "This feature is not implemented yet", "Lost connection to MySQL server at '%s', system error: %d", + "Statement closed indirectly because of a preceeding %s() call", "" }; @@ -209,6 +211,7 @@ const char *client_errors[]= "Attempt to read a row while there is no result set associated with the statement", "This feature is not implemented yet", "Lost connection to MySQL server at '%s', system error: %d", + "Statement closed indirectly because of a preceeding %s() call", "" }; #endif diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 181904edc1a..374676ebe32 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -715,7 +715,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, The server will close all statements no matter was the attempt to change user successful or not. */ - mysql_detach_stmt_list(&mysql->stmts); + mysql_detach_stmt_list(&mysql->stmts, "mysql_change_user"); if (rc == 0) { /* Free old connect information */ @@ -2872,7 +2872,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt) if (!mysql) { - set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); + /* Error is already set in mysql_detatch_stmt_list */ DBUG_RETURN(1); } diff --git a/sql-common/client.c b/sql-common/client.c index 89d69b4bd1f..d6fd98a1ed2 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -2596,24 +2596,32 @@ static void mysql_close_free(MYSQL *mysql) SYNOPSYS mysql_detach_stmt_list() stmt_list pointer to mysql->stmts + func_name name of calling function NOTE There is similar code in mysql_reconnect(), so changes here should also be reflected there. */ -void mysql_detach_stmt_list(LIST **stmt_list __attribute__((unused))) +void mysql_detach_stmt_list(LIST **stmt_list __attribute__((unused)), + const char *func_name) { #ifdef MYSQL_CLIENT /* Reset connection handle in all prepared statements. */ LIST *element= *stmt_list; + char buff[MYSQL_ERRMSG_SIZE]; + DBUG_ENTER("mysql_detach_stmt_list"); + + my_snprintf(buff, sizeof(buff)-1, ER(CR_STMT_CLOSED), func_name); for (; element; element= element->next) { MYSQL_STMT *stmt= (MYSQL_STMT *) element->data; + set_stmt_errmsg(stmt, buff, CR_STMT_CLOSED, unknown_sqlstate); stmt->mysql= 0; /* No need to call list_delete for statement here */ } *stmt_list= 0; + DBUG_VOID_RETURN; #endif /* MYSQL_CLIENT */ } @@ -2634,7 +2642,7 @@ void STDCALL mysql_close(MYSQL *mysql) } mysql_close_free_options(mysql); mysql_close_free(mysql); - mysql_detach_stmt_list(&mysql->stmts); + mysql_detach_stmt_list(&mysql->stmts, "mysql_close"); #ifndef TO_BE_DELETED /* free/close slave list */ if (mysql->rpl_pivot) diff --git a/sql/net_serv.cc b/sql/net_serv.cc index f4b940af898..778f82c92ef 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -298,7 +298,7 @@ void net_clear(NET *net, my_bool clear_buffer) { DBUG_PRINT("info",("skipped %d bytes from file: %s", count, vio_description(net->vio))); -#if defined(EXTRA_DEBUG) && (MYSQL_VERSION_ID < 50100) +#if defined(EXTRA_DEBUG) fprintf(stderr,"Error: net_clear() skipped %d bytes from file: %s\n", count, vio_description(net->vio)); #endif @@ -903,9 +903,12 @@ my_real_read(NET *net, ulong *complen) (int) net->buff[net->where_b + 3], net->pkt_nr)); #ifdef EXTRA_DEBUG + fflush(stdout); fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n", (int) net->buff[net->where_b + 3], (uint) (uchar) net->pkt_nr); + fflush(stderr); + DBUG_ASSERT(0); #endif } len= packet_error; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 43f534d5404..f7b53141f46 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -420,6 +420,7 @@ void THD::init_for_queries() void THD::change_user(void) { cleanup(); + killed= NOT_KILLED; cleanup_done= 0; init(); stmt_map.reset(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 46f76db28ad..9c9a41a81fe 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -784,7 +784,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, char *save_db; uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ? *passwd++ : strlen(passwd)); - uint dummy_errors, save_db_length, db_length, res; + uint dummy_errors, save_db_length, db_length; + int res; Security_context save_security_ctx= *thd->security_ctx; USER_CONN *save_user_connect; @@ -831,6 +832,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, /* authentication failure, we shall restore old user */ if (res > 0) my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0)); + else + thd->clear_error(); // Error already sent to client x_free(thd->security_ctx->user); *thd->security_ctx= save_security_ctx; thd->user_connect= save_user_connect; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 6b0092e3880..534f7a51e05 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -83,6 +83,7 @@ struct my_tests_st }; #define myheader(str) \ +DBUG_PRINT("test", ("name: %s", str)); \ if (opt_silent < 2) \ { \ fprintf(stdout, "\n\n#####################################\n"); \ @@ -90,7 +91,9 @@ if (opt_silent < 2) \ opt_count, str); \ fprintf(stdout, " \n#####################################\n"); \ } + #define myheader_r(str) \ +DBUG_PRINT("test", ("name: %s", str)); \ if (!opt_silent) \ { \ fprintf(stdout, "\n\n#####################################\n"); \ @@ -298,7 +301,7 @@ static void client_connect(ulong flag) mysql->reconnect= 1; if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); /* set AUTOCOMMIT to ON*/ mysql_autocommit(mysql, TRUE); @@ -321,7 +324,7 @@ static void client_connect(ulong flag) have_innodb= check_have_innodb(mysql); if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); } @@ -341,12 +344,13 @@ static void client_disconnect() mysql_query(mysql, query); if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); if (!opt_silent) fprintf(stdout, "\n closing the connection ..."); mysql_close(mysql); - fprintf(stdout, " OK\n"); + if (!opt_silent) + fprintf(stdout, "OK\n"); } } @@ -2498,7 +2502,7 @@ static void test_ps_query_cache() exit(1); } if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); mysql= lmysql; } @@ -4940,7 +4944,7 @@ static void test_stmt_close() } lmysql->reconnect= 1; if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); /* set AUTOCOMMIT to ON*/ @@ -7471,7 +7475,7 @@ static void test_prepare_grant() } lmysql->reconnect= 1; if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); mysql= lmysql; rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)"); @@ -7932,7 +7936,7 @@ static void test_drop_temp() } lmysql->reconnect= 1; if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); mysql= lmysql; rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')"); @@ -12018,16 +12022,24 @@ static void test_bug5315() stmt= mysql_stmt_init(mysql); rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); DIE_UNLESS(rc == 0); + if (!opt_silent) + printf("Excuting mysql_change_user\n"); mysql_change_user(mysql, opt_user, opt_password, current_db); + if (!opt_silent) + printf("Excuting mysql_stmt_execute\n"); rc= mysql_stmt_execute(stmt); DIE_UNLESS(rc != 0); if (rc) { if (!opt_silent) - printf("Got error (as expected):\n%s", mysql_stmt_error(stmt)); + printf("Got error (as expected): '%s'\n", mysql_stmt_error(stmt)); } /* check that connection is OK */ + if (!opt_silent) + printf("Excuting mysql_stmt_close\n"); mysql_stmt_close(stmt); + if (!opt_silent) + printf("Excuting mysql_stmt_init\n"); stmt= mysql_stmt_init(mysql); rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); DIE_UNLESS(rc == 0); @@ -12716,6 +12728,7 @@ static void test_rewind(void) /* retreive all result sets till we are at the end */ while(!mysql_stmt_fetch(stmt)) + if (!opt_silent) printf("fetched result:%ld\n", Data); DIE_UNLESS(rc != MYSQL_NO_DATA); @@ -12726,6 +12739,7 @@ static void test_rewind(void) /* now we should be able to fetch the results again */ /* but mysql_stmt_fetch returns MYSQL_NO_DATA */ while(!(rc= mysql_stmt_fetch(stmt))) + if (!opt_silent) printf("fetched result after seek:%ld\n", Data); DIE_UNLESS(rc == MYSQL_NO_DATA); @@ -13276,7 +13290,7 @@ static void test_bug8378() exit(1); } if (!opt_silent) - fprintf(stdout, " OK"); + fprintf(stdout, "OK"); len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4); @@ -13445,7 +13459,8 @@ static void test_bug9520() DIE_UNLESS(rc == MYSQL_NO_DATA); - printf("Fetched %d rows\n", row_count); + if (!opt_silent) + printf("Fetched %d rows\n", row_count); DBUG_ASSERT(row_count == 3); mysql_stmt_close(stmt); @@ -15345,8 +15360,28 @@ static void test_bug17667() myheader("test_bug17667"); + master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1); + strxmov(master_log_filename, opt_vardir, "/log/master.log", NullS); + if (!opt_silent) + printf("Opening '%s'\n", master_log_filename); + log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(0)); + free(master_log_filename); + + if (log_file == NULL) + { + if (!opt_silent) + { + printf("Could not find the log file, VARDIR/log/master.log, so " + "test_bug17667 is not run.\n" + "Run test from the mysql-test/mysql-test-run* program to set up " + "correct environment for this test.\n\n"); + } + return; + } + for (statement_cursor= statements; statement_cursor->buffer != NULL; - statement_cursor++) { + statement_cursor++) + { if (statement_cursor->qt == QT_NORMAL) { /* Run statement as normal query */ @@ -15357,10 +15392,10 @@ static void test_bug17667() else if (statement_cursor->qt == QT_PREPARED) { /* - Run as prepared statement + Run as prepared statement - NOTE! All these queries should be in the log twice, - one time for prepare and one time for execute + NOTE! All these queries should be in the log twice, + one time for prepare and one time for execute */ stmt= mysql_stmt_init(mysql); @@ -15383,66 +15418,49 @@ static void test_bug17667() rc= mysql_query(mysql, "flush logs"); myquery(rc); - master_log_filename = (char *) malloc(strlen(opt_vardir) + strlen("/log/master.log") + 1); - strcpy(master_log_filename, opt_vardir); - strcat(master_log_filename, "/log/master.log"); - printf("Opening '%s'\n", master_log_filename); - log_file= my_fopen(master_log_filename, (int) (O_RDONLY | O_BINARY), MYF(MY_WME)); - free(master_log_filename); + for (statement_cursor= statements; statement_cursor->buffer != NULL; + statement_cursor++) + { + int expected_hits= 1, hits= 0; + char line_buffer[MAX_TEST_QUERY_LENGTH*2]; + /* more than enough room for the query and some marginalia. */ - if (log_file != NULL) { + /* Prepared statments always occurs twice in log */ + if (statement_cursor->qt == QT_PREPARED) + expected_hits++; - for (statement_cursor= statements; statement_cursor->buffer != NULL; - statement_cursor++) { - int expected_hits= 1, hits= 0; - char line_buffer[MAX_TEST_QUERY_LENGTH*2]; - /* more than enough room for the query and some marginalia. */ + /* Loop until we found expected number of log entries */ + do { + /* Loop until statement is found in log */ + do { + memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2); - /* Prepared statments always occurs twice in log */ - if (statement_cursor->qt == QT_PREPARED) - expected_hits++; + if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL) + { + /* If fgets returned NULL, it indicates either error or EOF */ + if (feof(log_file)) + DIE("Found EOF before all statements where found"); - /* Loop until we found expected number of log entries */ - do { - /* Loop until statement is found in log */ - do { - memset(line_buffer, '/', MAX_TEST_QUERY_LENGTH*2); - - if(fgets(line_buffer, MAX_TEST_QUERY_LENGTH*2, log_file) == NULL) - { - /* If fgets returned NULL, it indicates either error or EOF */ - if (feof(log_file)) - DIE("Found EOF before all statements where found"); - - fprintf(stderr, "Got error %d while reading from file\n", - ferror(log_file)); - DIE("Read error"); - } - - } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2, - statement_cursor->buffer, - statement_cursor->length) == NULL); - hits++; - } while (hits < expected_hits); + fprintf(stderr, "Got error %d while reading from file\n", + ferror(log_file)); + DIE("Read error"); + } + + } while (my_memmem(line_buffer, MAX_TEST_QUERY_LENGTH*2, + statement_cursor->buffer, + statement_cursor->length) == NULL); + hits++; + } while (hits < expected_hits); + if (!opt_silent) printf("Found statement starting with \"%s\"\n", statement_cursor->buffer); - } - - printf("success. All queries found intact in the log.\n"); - - } - else - { - fprintf(stderr, "Could not find the log file, VARDIR/log/master.log, so " - "test_bug17667 is \ninconclusive. Run test from the " - "mysql-test/mysql-test-run* program \nto set up the correct " - "environment for this test.\n\n"); } - if (log_file != NULL) - my_fclose(log_file, MYF(0)); + if (!opt_silent) + printf("success. All queries found intact in the log.\n"); + my_fclose(log_file, MYF(0)); } @@ -16008,12 +16026,14 @@ static void test_bug21635() for (i= 0; i < field_count; ++i) { field= mysql_fetch_field_direct(result, i); - printf("%s -> %s ... ", expr[i * 2], field->name); + if (!opt_silent) + printf("%s -> %s ... ", expr[i * 2], field->name); fflush(stdout); DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 && field->table[0] == 0 && field->org_name[0] == 0); DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0); - puts("OK"); + if (!opt_silent) + puts("OK"); } mysql_free_result(result); |