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
parent 4a065f5f
......@@ -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. */
......@@ -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,
......
......@@ -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
......
......@@ -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);
}
......
......@@ -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)
......
......@@ -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;
......
......@@ -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();
......
......@@ -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;
......
......@@ -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,6 +13459,7 @@ static void test_bug9520()
DIE_UNLESS(rc == MYSQL_NO_DATA);
if (!opt_silent)
printf("Fetched %d rows\n", row_count);
DBUG_ASSERT(row_count == 3);
......@@ -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 */
......@@ -15383,17 +15418,9 @@ 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);
if (log_file != NULL) {
for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) {
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. */
......@@ -15425,24 +15452,15 @@ static void test_bug17667()
hits++;
} while (hits < expected_hits);
if (!opt_silent)
printf("Found statement starting with \"%s\"\n",
statement_cursor->buffer);
}
if (!opt_silent)
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));
}
......@@ -16008,11 +16026,13 @@ static void test_bug21635()
for (i= 0; i < field_count; ++i)
{
field= mysql_fetch_field_direct(result, i);
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);
if (!opt_silent)
puts("OK");
}
......
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