summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <monty@mysql.com/narttu.mysql.fi>2007-04-13 01:56:22 +0300
committerunknown <monty@mysql.com/narttu.mysql.fi>2007-04-13 01:56:22 +0300
commitf3efb3dcfac96afa487709f2603784f60f021f61 (patch)
tree2eec82067ee6e913dcb025424b04b00c7e81c1cf
parent2671ba02300bf94df7d987c1e594ca2e022e9a69 (diff)
downloadmariadb-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.h3
-rw-r--r--libmysql/client_settings.h2
-rw-r--r--libmysql/errmsg.c3
-rw-r--r--libmysql/libmysql.c4
-rw-r--r--sql-common/client.c12
-rw-r--r--sql/net_serv.cc5
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_parse.cc5
-rw-r--r--tests/mysql_client_test.c154
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);