Commit f3efb3dc authored by unknown's avatar unknown

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
parent 2671ba02
...@@ -95,6 +95,7 @@ extern const char *client_errors[]; /* Error messages */ ...@@ -95,6 +95,7 @@ extern const char *client_errors[]; /* Error messages */
#define CR_NO_RESULT_SET 2053 #define CR_NO_RESULT_SET 2053
#define CR_NOT_IMPLEMENTED 2054 #define CR_NOT_IMPLEMENTED 2054
#define CR_SERVER_LOST_EXTENDED 2055 #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. */ /* 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); ...@@ -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, void mysql_read_default_options(struct st_mysql_options *options,
const char *filename,const char *group); 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 * MYSQL *
cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user, cli_mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
const char *passwd, const char *db, const char *passwd, const char *db,
......
...@@ -83,6 +83,7 @@ const char *client_errors[]= ...@@ -83,6 +83,7 @@ const char *client_errors[]=
"Attempt to read a row while there is no result set associated with the statement", "Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet", "This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d", "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[]= ...@@ -147,6 +148,7 @@ const char *client_errors[]=
"Attempt to read a row while there is no result set associated with the statement", "Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet", "This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d", "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[]= ...@@ -209,6 +211,7 @@ const char *client_errors[]=
"Attempt to read a row while there is no result set associated with the statement", "Attempt to read a row while there is no result set associated with the statement",
"This feature is not implemented yet", "This feature is not implemented yet",
"Lost connection to MySQL server at '%s', system error: %d", "Lost connection to MySQL server at '%s', system error: %d",
"Statement closed indirectly because of a preceeding %s() call",
"" ""
}; };
#endif #endif
......
...@@ -715,7 +715,7 @@ my_bool STDCALL mysql_change_user(MYSQL *mysql, const char *user, ...@@ -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 The server will close all statements no matter was the attempt
to change user successful or not. to change user successful or not.
*/ */
mysql_detach_stmt_list(&mysql->stmts); mysql_detach_stmt_list(&mysql->stmts, "mysql_change_user");
if (rc == 0) if (rc == 0)
{ {
/* Free old connect information */ /* Free old connect information */
...@@ -2872,7 +2872,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt) ...@@ -2872,7 +2872,7 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
if (!mysql) if (!mysql)
{ {
set_stmt_error(stmt, CR_SERVER_LOST, unknown_sqlstate); /* Error is already set in mysql_detatch_stmt_list */
DBUG_RETURN(1); DBUG_RETURN(1);
} }
......
...@@ -2596,24 +2596,32 @@ static void mysql_close_free(MYSQL *mysql) ...@@ -2596,24 +2596,32 @@ static void mysql_close_free(MYSQL *mysql)
SYNOPSYS SYNOPSYS
mysql_detach_stmt_list() mysql_detach_stmt_list()
stmt_list pointer to mysql->stmts stmt_list pointer to mysql->stmts
func_name name of calling function
NOTE NOTE
There is similar code in mysql_reconnect(), so changes here There is similar code in mysql_reconnect(), so changes here
should also be reflected there. 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 #ifdef MYSQL_CLIENT
/* Reset connection handle in all prepared statements. */ /* Reset connection handle in all prepared statements. */
LIST *element= *stmt_list; 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) for (; element; element= element->next)
{ {
MYSQL_STMT *stmt= (MYSQL_STMT *) element->data; MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
set_stmt_errmsg(stmt, buff, CR_STMT_CLOSED, unknown_sqlstate);
stmt->mysql= 0; stmt->mysql= 0;
/* No need to call list_delete for statement here */ /* No need to call list_delete for statement here */
} }
*stmt_list= 0; *stmt_list= 0;
DBUG_VOID_RETURN;
#endif /* MYSQL_CLIENT */ #endif /* MYSQL_CLIENT */
} }
...@@ -2634,7 +2642,7 @@ void STDCALL mysql_close(MYSQL *mysql) ...@@ -2634,7 +2642,7 @@ void STDCALL mysql_close(MYSQL *mysql)
} }
mysql_close_free_options(mysql); mysql_close_free_options(mysql);
mysql_close_free(mysql); mysql_close_free(mysql);
mysql_detach_stmt_list(&mysql->stmts); mysql_detach_stmt_list(&mysql->stmts, "mysql_close");
#ifndef TO_BE_DELETED #ifndef TO_BE_DELETED
/* free/close slave list */ /* free/close slave list */
if (mysql->rpl_pivot) if (mysql->rpl_pivot)
......
...@@ -298,7 +298,7 @@ void net_clear(NET *net, my_bool clear_buffer) ...@@ -298,7 +298,7 @@ void net_clear(NET *net, my_bool clear_buffer)
{ {
DBUG_PRINT("info",("skipped %d bytes from file: %s", DBUG_PRINT("info",("skipped %d bytes from file: %s",
count, vio_description(net->vio))); 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", fprintf(stderr,"Error: net_clear() skipped %d bytes from file: %s\n",
count, vio_description(net->vio)); count, vio_description(net->vio));
#endif #endif
...@@ -903,9 +903,12 @@ my_real_read(NET *net, ulong *complen) ...@@ -903,9 +903,12 @@ my_real_read(NET *net, ulong *complen)
(int) net->buff[net->where_b + 3], (int) net->buff[net->where_b + 3],
net->pkt_nr)); net->pkt_nr));
#ifdef EXTRA_DEBUG #ifdef EXTRA_DEBUG
fflush(stdout);
fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n", fprintf(stderr,"Error: Packets out of order (Found: %d, expected %d)\n",
(int) net->buff[net->where_b + 3], (int) net->buff[net->where_b + 3],
(uint) (uchar) net->pkt_nr); (uint) (uchar) net->pkt_nr);
fflush(stderr);
DBUG_ASSERT(0);
#endif #endif
} }
len= packet_error; len= packet_error;
......
...@@ -420,6 +420,7 @@ void THD::init_for_queries() ...@@ -420,6 +420,7 @@ void THD::init_for_queries()
void THD::change_user(void) void THD::change_user(void)
{ {
cleanup(); cleanup();
killed= NOT_KILLED;
cleanup_done= 0; cleanup_done= 0;
init(); init();
stmt_map.reset(); stmt_map.reset();
......
...@@ -784,7 +784,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -784,7 +784,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
char *save_db; char *save_db;
uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ? uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
*passwd++ : strlen(passwd)); *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; Security_context save_security_ctx= *thd->security_ctx;
USER_CONN *save_user_connect; USER_CONN *save_user_connect;
...@@ -831,6 +832,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd, ...@@ -831,6 +832,8 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* authentication failure, we shall restore old user */ /* authentication failure, we shall restore old user */
if (res > 0) if (res > 0)
my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(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); x_free(thd->security_ctx->user);
*thd->security_ctx= save_security_ctx; *thd->security_ctx= save_security_ctx;
thd->user_connect= save_user_connect; thd->user_connect= save_user_connect;
......
...@@ -83,6 +83,7 @@ struct my_tests_st ...@@ -83,6 +83,7 @@ struct my_tests_st
}; };
#define myheader(str) \ #define myheader(str) \
DBUG_PRINT("test", ("name: %s", str)); \
if (opt_silent < 2) \ if (opt_silent < 2) \
{ \ { \
fprintf(stdout, "\n\n#####################################\n"); \ fprintf(stdout, "\n\n#####################################\n"); \
...@@ -90,7 +91,9 @@ if (opt_silent < 2) \ ...@@ -90,7 +91,9 @@ if (opt_silent < 2) \
opt_count, str); \ opt_count, str); \
fprintf(stdout, " \n#####################################\n"); \ fprintf(stdout, " \n#####################################\n"); \
} }
#define myheader_r(str) \ #define myheader_r(str) \
DBUG_PRINT("test", ("name: %s", str)); \
if (!opt_silent) \ if (!opt_silent) \
{ \ { \
fprintf(stdout, "\n\n#####################################\n"); \ fprintf(stdout, "\n\n#####################################\n"); \
...@@ -298,7 +301,7 @@ static void client_connect(ulong flag) ...@@ -298,7 +301,7 @@ static void client_connect(ulong flag)
mysql->reconnect= 1; mysql->reconnect= 1;
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
/* set AUTOCOMMIT to ON*/ /* set AUTOCOMMIT to ON*/
mysql_autocommit(mysql, TRUE); mysql_autocommit(mysql, TRUE);
...@@ -321,7 +324,7 @@ static void client_connect(ulong flag) ...@@ -321,7 +324,7 @@ static void client_connect(ulong flag)
have_innodb= check_have_innodb(mysql); have_innodb= check_have_innodb(mysql);
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
} }
...@@ -341,12 +344,13 @@ static void client_disconnect() ...@@ -341,12 +344,13 @@ static void client_disconnect()
mysql_query(mysql, query); mysql_query(mysql, query);
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
if (!opt_silent) if (!opt_silent)
fprintf(stdout, "\n closing the connection ..."); fprintf(stdout, "\n closing the connection ...");
mysql_close(mysql); mysql_close(mysql);
fprintf(stdout, " OK\n"); if (!opt_silent)
fprintf(stdout, "OK\n");
} }
} }
...@@ -2498,7 +2502,7 @@ static void test_ps_query_cache() ...@@ -2498,7 +2502,7 @@ static void test_ps_query_cache()
exit(1); exit(1);
} }
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
mysql= lmysql; mysql= lmysql;
} }
...@@ -4940,7 +4944,7 @@ static void test_stmt_close() ...@@ -4940,7 +4944,7 @@ static void test_stmt_close()
} }
lmysql->reconnect= 1; lmysql->reconnect= 1;
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
/* set AUTOCOMMIT to ON*/ /* set AUTOCOMMIT to ON*/
...@@ -7471,7 +7475,7 @@ static void test_prepare_grant() ...@@ -7471,7 +7475,7 @@ static void test_prepare_grant()
} }
lmysql->reconnect= 1; lmysql->reconnect= 1;
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
mysql= lmysql; mysql= lmysql;
rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)"); rc= mysql_query(mysql, "INSERT INTO test_grant VALUES(NULL)");
...@@ -7932,7 +7936,7 @@ static void test_drop_temp() ...@@ -7932,7 +7936,7 @@ static void test_drop_temp()
} }
lmysql->reconnect= 1; lmysql->reconnect= 1;
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
mysql= lmysql; mysql= lmysql;
rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')"); rc= mysql_query(mysql, "INSERT INTO t1 VALUES(10, 'C')");
...@@ -12018,16 +12022,24 @@ static void test_bug5315() ...@@ -12018,16 +12022,24 @@ static void test_bug5315()
stmt= mysql_stmt_init(mysql); stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
DIE_UNLESS(rc == 0); DIE_UNLESS(rc == 0);
if (!opt_silent)
printf("Excuting mysql_change_user\n");
mysql_change_user(mysql, opt_user, opt_password, current_db); mysql_change_user(mysql, opt_user, opt_password, current_db);
if (!opt_silent)
printf("Excuting mysql_stmt_execute\n");
rc= mysql_stmt_execute(stmt); rc= mysql_stmt_execute(stmt);
DIE_UNLESS(rc != 0); DIE_UNLESS(rc != 0);
if (rc) if (rc)
{ {
if (!opt_silent) 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 */ /* check that connection is OK */
if (!opt_silent)
printf("Excuting mysql_stmt_close\n");
mysql_stmt_close(stmt); mysql_stmt_close(stmt);
if (!opt_silent)
printf("Excuting mysql_stmt_init\n");
stmt= mysql_stmt_init(mysql); stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
DIE_UNLESS(rc == 0); DIE_UNLESS(rc == 0);
...@@ -12716,6 +12728,7 @@ static void test_rewind(void) ...@@ -12716,6 +12728,7 @@ static void test_rewind(void)
/* retreive all result sets till we are at the end */ /* retreive all result sets till we are at the end */
while(!mysql_stmt_fetch(stmt)) while(!mysql_stmt_fetch(stmt))
if (!opt_silent)
printf("fetched result:%ld\n", Data); printf("fetched result:%ld\n", Data);
DIE_UNLESS(rc != MYSQL_NO_DATA); DIE_UNLESS(rc != MYSQL_NO_DATA);
...@@ -12726,6 +12739,7 @@ static void test_rewind(void) ...@@ -12726,6 +12739,7 @@ static void test_rewind(void)
/* now we should be able to fetch the results again */ /* now we should be able to fetch the results again */
/* but mysql_stmt_fetch returns MYSQL_NO_DATA */ /* but mysql_stmt_fetch returns MYSQL_NO_DATA */
while(!(rc= mysql_stmt_fetch(stmt))) while(!(rc= mysql_stmt_fetch(stmt)))
if (!opt_silent)
printf("fetched result after seek:%ld\n", Data); printf("fetched result after seek:%ld\n", Data);
DIE_UNLESS(rc == MYSQL_NO_DATA); DIE_UNLESS(rc == MYSQL_NO_DATA);
...@@ -13276,7 +13290,7 @@ static void test_bug8378() ...@@ -13276,7 +13290,7 @@ static void test_bug8378()
exit(1); exit(1);
} }
if (!opt_silent) if (!opt_silent)
fprintf(stdout, " OK"); fprintf(stdout, "OK");
len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4); len= mysql_real_escape_string(mysql, out, TEST_BUG8378_IN, 4);
...@@ -13445,6 +13459,7 @@ static void test_bug9520() ...@@ -13445,6 +13459,7 @@ static void test_bug9520()
DIE_UNLESS(rc == MYSQL_NO_DATA); DIE_UNLESS(rc == MYSQL_NO_DATA);
if (!opt_silent)
printf("Fetched %d rows\n", row_count); printf("Fetched %d rows\n", row_count);
DBUG_ASSERT(row_count == 3); DBUG_ASSERT(row_count == 3);
...@@ -15345,8 +15360,28 @@ static void test_bug17667() ...@@ -15345,8 +15360,28 @@ static void test_bug17667()
myheader("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; for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) { statement_cursor++)
{
if (statement_cursor->qt == QT_NORMAL) if (statement_cursor->qt == QT_NORMAL)
{ {
/* Run statement as normal query */ /* Run statement as normal query */
...@@ -15383,17 +15418,9 @@ static void test_bug17667() ...@@ -15383,17 +15418,9 @@ static void test_bug17667()
rc= mysql_query(mysql, "flush logs"); rc= mysql_query(mysql, "flush logs");
myquery(rc); 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; for (statement_cursor= statements; statement_cursor->buffer != NULL;
statement_cursor++) { statement_cursor++)
{
int expected_hits= 1, hits= 0; int expected_hits= 1, hits= 0;
char line_buffer[MAX_TEST_QUERY_LENGTH*2]; char line_buffer[MAX_TEST_QUERY_LENGTH*2];
/* more than enough room for the query and some marginalia. */ /* more than enough room for the query and some marginalia. */
...@@ -15425,24 +15452,15 @@ static void test_bug17667() ...@@ -15425,24 +15452,15 @@ static void test_bug17667()
hits++; hits++;
} while (hits < expected_hits); } while (hits < expected_hits);
if (!opt_silent)
printf("Found statement starting with \"%s\"\n", printf("Found statement starting with \"%s\"\n",
statement_cursor->buffer); statement_cursor->buffer);
} }
if (!opt_silent)
printf("success. All queries found intact in the log.\n"); 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)); my_fclose(log_file, MYF(0));
} }
...@@ -16008,11 +16026,13 @@ static void test_bug21635() ...@@ -16008,11 +16026,13 @@ static void test_bug21635()
for (i= 0; i < field_count; ++i) for (i= 0; i < field_count; ++i)
{ {
field= mysql_fetch_field_direct(result, i); field= mysql_fetch_field_direct(result, i);
if (!opt_silent)
printf("%s -> %s ... ", expr[i * 2], field->name); printf("%s -> %s ... ", expr[i * 2], field->name);
fflush(stdout); fflush(stdout);
DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 && DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
field->table[0] == 0 && field->org_name[0] == 0); field->table[0] == 0 && field->org_name[0] == 0);
DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0); DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
if (!opt_silent)
puts("OK"); 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