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 );