diff options
author | unknown <msvensson@neptunus.(none)> | 2007-01-16 13:39:42 +0100 |
---|---|---|
committer | unknown <msvensson@neptunus.(none)> | 2007-01-16 13:39:42 +0100 |
commit | 7b965030418e9460c9f0324cdea0f0decd9686ee (patch) | |
tree | c33a821cc43b96773ccb3649535c3122cf5a87b9 /libmysql | |
parent | 89d106c1a4efad141e7850373335482ad46aeec5 (diff) | |
download | mariadb-git-7b965030418e9460c9f0324cdea0f0decd9686ee.tar.gz |
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.
Diffstat (limited to 'libmysql')
-rw-r--r-- | libmysql/libmysql.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 6a592f64e49..a5dcb66f002 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -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)) |