Description:
If a stored procedure executed by a prepared statement, after delete the sql::PreparedStatement object, the prepared statement will not released by the server side. After a long time run, the program will hit the "Can't create more than max_prepared_stmt_count statements" problem finally.
How to repeat:
#include <stdlib.h>
#include <iostream>
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
#include <cppconn/prepared_statement.h>
using namespace std;
using namespace sql;
int main(void){
try {
sql::Driver *driver;
sql::Connection *con;
driver = get_driver_instance();
con = driver->connect("tcp://127.0.0.1:3306", "root", "root");
con->setSchema("test");
sql::PreparedStatement *pstmt;
sql::ResultSet * res;
/*
CREATE PROCEDURE `plus`(a int, b int)
begin
select a + b as result;
end
*/
pstmt = con->prepareStatement("CALL plus(?, ?)");
pstmt->setInt(1, 1);
pstmt->setInt(2, 2);
res = pstmt->executeQuery();
if (res->first()){
cout << "first" << endl;
while (res->next()){
cout << "next" << endl;
}
}
// Without pstmt->getMoreResults(), the prepared statement
// will not released on the server side.
// cout << pstmt->getMoreResults() << endl;
delete res;
delete pstmt;
delete con;
} catch (sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line "
<< __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
return EXIT_SUCCESS;
}
Suggested fix:
Throw an exception when the return value of mysql_stmt_close() is not zero, or invoke getMoreResults() automatically in ~MySQL_Prepared_Statement().