Bug #49466 SQLMoreResults does not set statement errors correctly
Submitted: 4 Dec 2009 21:32 Modified: 3 Jul 2018 22:07
Reporter: Steven Cain Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / ODBC Severity:S3 (Non-critical)
Version:3.51.27 OS:Windows
Assigned to: Bogdan Degtyariov CPU Architecture:Any

[4 Dec 2009 21:32] Steven Cain
Description:
If an error occurs while executing multiple statements in a single query SQLMoreResults does not set the statement error string with the error returned by the server.  SQLMoreResults returns "unhandled error from mysql_next_result()" along with the correct error number returned from the server.  The error string returned from the server is not accessible to the calling application through the ODBC connector.

How to repeat:
#include <afx.h>
#include <sqlext.h>

int main(int argc, char* argv[])
{
  SQLHENV hEnv;
  SQLHDBC hDbc;
  // Put the server, username, and password here.
  // 67108864 Turns on multiple statement support.
  char *szConnectString = "DRIVER={MySQL ODBC 3.51 Driver};OPTION=67108864;SERVER=mysqlserver;Database=test;Uid=user;Pwd=pw;";
  char *szQuery = "SET @Temp=1;CALL NonExistentProc()";
  SQLRETURN ret;
  SQLHSTMT hStmt;
  short sNumberOfColumns;
  bool bContinue = true;
  SQLSMALLINT iMessageLength;
  unsigned char szState[16];
  long lNativeError;
  unsigned char szMessage[128];

  ret = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &hEnv);
  ret = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (void*)SQL_OV_ODBC3, 0);
  ret = SQLAllocHandle(SQL_HANDLE_DBC, hEnv, &hDbc);

  // Connect to the database.
  ret = SQLDriverConnect(hDbc,
              NULL,
              (SQLCHAR*)szConnectString,
              strlen(szConnectString),
              NULL,
              0,
              NULL,
              (SQLUSMALLINT)SQL_DRIVER_NOPROMPT);

  ret = SQLAllocHandle(SQL_HANDLE_STMT, hDbc, &hStmt);

  // Execute the query.
  ret = SQLExecDirect(hStmt, (SQLCHAR*)(szQuery), SQL_NTS);
  if(ret == SQL_SUCCESS)
  {
    do
    {
      ret = SQLNumResultCols(hStmt, &sNumberOfColumns);
      // If sNumberOfColumns == 0 there is nothing to fetch.
      if(ret == SQL_SUCCESS && sNumberOfColumns > 0)
      {
        ret = SQLFetch(hStmt);
        // Do any resultset processing here.
      }

      // Get the next resultset.
      ret = SQLMoreResults(hStmt);
      if(ret != SQL_SUCCESS)
      {
        SQLRETURN ret;

        // Get the error.
        ret = SQLGetDiagRec(SQL_HANDLE_STMT,
          hStmt,
          1,
          szState,
          &lNativeError,
          szMessage,
          sizeof(szMessage),
          &iMessageLength);

        // lNativeError is set to 1305 here but szMessage is not set to "PROCEDURE NonExistentProc does not exist"

        printf("%s %d %s\n", szState, lNativeError, szMessage);
        bContinue = false;
      }
    }
    while(bContinue);
  }

  ret = SQLDisconnect(hDbc);

  ret = SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
  ret = SQLFreeHandle(SQL_HANDLE_ENV, hEnv);

  return 0;
}

Suggested fix:
Modify SQLMoreResults in results.c 

Replace
  nReturn = set_stmt_error( pStmt, "HY000", "unhandled error from mysql_next_result()", nRetVal );

with

  nReturn = set_stmt_error( pStmt, "HY000", mysql_error( &pStmt->dbc->mysql ), nRetVal );
[7 Dec 2009 7:16] Tonci Grgin
Hi Steven and thanks for your reasonable feature request.
[29 Jun 2018 4:34] Bogdan Degtyariov
Posted by developer:
 
The patch fixes the unspecific error for multiple statements.
Now the error message has the context like:

[MySQL][ODBC 5.3(w) Driver][mysqld-8.0.12-gpl-log] PROCEDURE test.NonExistentProc does not exist
[3 Jul 2018 22:07] Philip Olson
Posted by developer:
 
Fixed as of the upcoming MySQL Connector/ODBC 5.3.11 release, and here's the changelog entry:

Reported errors that occurred while executing multiple statements with a
single query were generic and without context. For example, SQLMoreResults
might return "unhandled error from mysql_next_result()" instead of the
error reported by MySQL Server.

Thank you for the bug report.