Bug #64044 Could not handle multiple INSERTs with C++ connector
Submitted: 16 Jan 2012 18:57 Modified: 3 Jun 2022 16:17
Reporter: Gilberto Queiroz Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / C++ Severity:S3 (Non-critical)
Version:1.1.0 OS:Windows
Assigned to: CPU Architecture:Any
Tags: Contribution

[16 Jan 2012 18:57] Gilberto Queiroz
Description:
I'm trying to use MySQL Connector C++ in order to handle multiple inserts but the Statement's method getMoreResults() always returns false and getUpdateCount() returns a fixed value (with the result of the first insert).

Successive calls to statement's execute method start to fail because the connection hasn't stopped on an appropriated state.

I have added the following lines to mysql_statement.cpp to enforce a call to affected_rows(), returning true if proxy->field_count() == 0, instead of false:

bool
MySQL_Statement::getMoreResults()
{
...
else if (next_result == 0) {
      if(proxy->field_count() == 0)
      {
        last_update_count = proxy->affected_rows();
        return true;
      }else
      {
        throw sql::SQLException("Could not retrieve result set");
      }
...
}

How to repeat:
Then the following code example started to work:

std::auto_ptr<sql::Statement> stmt(conn->createStatement());

while(...)
{
  ...

  stmt->execute(buff); // maybe multiple inserts separated by ";"

  while(stmt->getMoreResults())
    std::auto_ptr<sql::ResultSet> res(stmt->getResultSet());

  ...
}

Suggested fix:
/* {{{ MySQL_Statement::getMoreResults() -I- */
bool
MySQL_Statement::getMoreResults()
{
	CPP_ENTER("MySQL_Statement::getMaxRows");
	CPP_INFO_FMT("this=%p", this);
	checkClosed();
	last_update_count = UL64(~0);
	if (proxy->more_results()) {
		int next_result = proxy->next_result();
		if (next_result > 0) {
			CPP_ERR_FMT("Error during getMoreResults : %d:(%s) %s", proxy->errNo(), proxy->sqlstate().c_str(), proxy->error().c_str());
			sql::mysql::util::throwSQLException(*proxy.get());
		} else if (next_result == 0) {
// field_count() == 0 implies we need to call proxy->affected_rows()
      if(proxy->field_count() == 0)
      {
        last_update_count = proxy->affected_rows();
        return true;
      }else
      {
        throw sql::SQLException("Could not retrieve result set");
      }
		} else if (next_result == -1) {
			throw sql::SQLException("Impossible! more_results() said true, next_result says no more results");
		}
	}
	return false;
}
[19 Jan 2012 18:26] Sveta Smirnova
Thank you for the report.

Please provide full test case demonstrating the problem.
[25 Jan 2012 0:50] Gilberto Queiroz
Hi Sveta Smirnova,

thanks for your reply.

I have attached a simple test case.

Best regards, Gilberto
[30 Jan 2012 18:14] Sveta Smirnova
Thank you for the feedback.

Verified as described.
[23 Apr 2013 21:04] Lawrenty Novitsky
That bug could be fixed(at least partly) in 1.1.2
[3 Jun 2022 16:17] Luis Silva
Posted by developer:
 
According to the JDBC docs, getMoreResults returns true if the returned result is a result set, otherwise, false.

In your scenario, you are inserting data, so the getMoreResults() will always return false.

To check properly if you gather all OK messages, you should check the getUpdateCount() (keep in mind that its status is clean (~0uul) after calling it.

So proper way to not get the full results is:

  stmt->execute(insert1); // ok

  while (stmt->getMoreResults() || stmt->getUpdateCount() != ~0ull)
  {
    std::cout << "Still has results" << std::endl;
  }
  // Can now insert more data
  stmt->execute(insert2); // ok