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:
@ -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))
|
||||
|
Reference in New Issue
Block a user