1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Bug#15518 Reusing a stmt that has failed during prepare does not clear error

- Always reset error when calling mysql_stmt_prepare a second time
 - Set stmt->state to MYSQL_STMT_INIT_DONE before closing prepared stmt in server.
 - Add test to mysql_client_test
 - Remove mysql_stmt_close in mysqltest after each query
 - Close all open statements in mysqltest if disable_ps_protocol is called. 


client/mysqltest.c:
  Don't close the statement after each query - reprepare it in next query.
  When "disable_ps_protocol" is issued make sure to close all open
  statements. Otherwise the test for @@max_prepared_statements fails. But we
  also get a test that the statements that are open can be closed and reopened
  in the middle of the tests.
libmysql/libmysql.c:
  Reset the last error every time mysql_stmt_prepare is called.
  Set state to MYSQL_STMT_INIT_DONE befoe closing it in the server. That way
  we will always have right status regardless of wheter close fails or not.
tests/mysql_client_test.c:
  Add testcase for bug15518, re-prepare a previously prepare statement that has failed
  to prepare. Test also when connection to server has been lost inbetween.
  Change all assert to DIE_UNLESS so we get printout of line and an error message
  if it fails.
This commit is contained in:
unknown
2007-01-16 13:39:42 +01:00
parent 89d106c1a4
commit 7b96503041
3 changed files with 117 additions and 15 deletions

View File

@ -2038,6 +2038,13 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
DBUG_RETURN(1);
}
/*
Reset the last error in any case: that would clear the statement
if the previous prepare failed.
*/
stmt->last_errno= 0;
stmt->last_error[0]= '\0';
if ((int) stmt->state > (int) MYSQL_STMT_INIT_DONE)
{
/* This is second prepare with another statement */
@ -2051,23 +2058,24 @@ mysql_stmt_prepare(MYSQL_STMT *stmt, const char *query, ulong length)
*/
stmt->bind_param_done= stmt->bind_result_done= FALSE;
stmt->param_count= stmt->field_count= 0;
stmt->last_errno= 0;
stmt->last_error[0]= '\0';
free_root(&stmt->mem_root, MYF(MY_KEEP_PREALLOC));
int4store(buff, stmt->stmt_id);
/*
Close statement in server
If there was a 'use' result from another statement, or from
mysql_use_result it won't be freed in mysql_stmt_free_result and
we should get 'Commands out of sync' here.
*/
stmt->state= MYSQL_STMT_INIT_DONE;
if (stmt_command(mysql, COM_STMT_CLOSE, buff, 4, stmt))
{
set_stmt_errmsg(stmt, mysql->net.last_error, mysql->net.last_errno,
mysql->net.sqlstate);
DBUG_RETURN(1);
}
stmt->state= MYSQL_STMT_INIT_DONE;
}
if (stmt_command(mysql, COM_STMT_PREPARE, query, length, stmt))