List:Commits« Previous MessageNext Message »
From:pharvey Date:May 26 2006 11:21pm
Subject:Connector/ODBC 5 commit: r274 - MYSQLPlus/MYSQLPlusLib
View as plain text  
Modified:
   MYSQLPlus/MYSQLPlusLib/MDescriptor.cpp
   MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp
   MYSQLPlus/MYSQLPlusLib/MResult.cpp
   MYSQLPlus/MYSQLPlusLib/MResult.h
   MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp
   MYSQLPlus/MYSQLPlusLib/MResultRes.cpp
   MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp
   MYSQLPlus/MYSQLPlusLib/MStatement.cpp
Log:


Modified: MYSQLPlus/MYSQLPlusLib/MDescriptor.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MDescriptor.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MDescriptor.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -25,7 +25,13 @@
 
     pConnection->getDiagnostic()->doClear();
 
-    /* we only want MDescriptorRecord* children so create MDiagnostic without it being a
child of this */
+    /*!
+        \internal
+        \note
+         
+        We only want MDescriptorRecord* children so create MDiagnostic without it being a
child of this. We
+        do this to help with performance. 
+    */
     pDiagnostic = new MDiagnostic();
     nAllocType  = SQL_DESC_ALLOC_USER;
     doInit();

Modified: MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MDiagnostic.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -294,6 +294,17 @@
     switch ( nDiagIdentifier )
     {
         case SQL_DIAG_CURSOR_ROW_COUNT:
+            /*!
+                \internal ODBC RULE
+
+                An application can call SQLGetDiagField to return any diagnostic field at
any time, with the exception of SQL_DIAG_CURSOR_ROW_COUNT or 
+                SQL_DIAG_ROW_COUNT, which will return SQL_ERROR if Handle is not a
statement handle. If any other diagnostic field is undefined, the 
+                call to SQLGetDiagField will return SQL_SUCCESS (provided no other
diagnostic is encountered) and an undefined value is returned for 
+                the field.
+            */
+            if ( parent() && parent()->className() != "MStatement" )
+                MYODBCDbgReturn( SQL_ERROR );
+
             *(SQLINTEGER*)pDiagInfoPtr = getCursorRowCount();
             break;
 
@@ -322,8 +333,20 @@
             break;
 
         case SQL_DIAG_ROW_COUNT:
+            /*!
+                \internal ODBC RULE
+
+                An application can call SQLGetDiagField to return any diagnostic field at
any time, with the exception of SQL_DIAG_CURSOR_ROW_COUNT or 
+                SQL_DIAG_ROW_COUNT, which will return SQL_ERROR if Handle is not a
statement handle. If any other diagnostic field is undefined, the 
+                call to SQLGetDiagField will return SQL_SUCCESS (provided no other
diagnostic is encountered) and an undefined value is returned for 
+                the field.
+            */
+            if ( parent() && parent()->className() != "MStatement" )
+                MYODBCDbgReturn( SQL_ERROR );
+
             *(SQLINTEGER*)pDiagInfoPtr = getRowCount();
             break;
+
         default:
             if ( nRecNumber < 1 )
                 MYODBCDbgReturn( SQL_ERROR );
@@ -687,7 +710,7 @@
         because the SQL_DIAG_ROW_COUNT field is reset to 0 by any function 
         call.
 
-        see SQLRowCount
+        \sa SQLRowCount
     */      
     nRowCount = 0;
 

Modified: MYSQLPlus/MYSQLPlusLib/MResult.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResult.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MResult.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -94,8 +94,10 @@
 
     Q_ASSERT( !pStatement );
 
-    nState      = STATE_UNINITIALIZED;
-    bBuffered   = true;
+    nState          = STATE_UNINITIALIZED;
+    bBuffered       = true;
+    nRowsAffected   = 0;
+    nStatementType  = STATEMENT_TYPE_NULL;
     pStatement->getImpParamDesc()->doClear();
     pStatement->getImpRowDesc()->doClear();
 
@@ -324,6 +326,13 @@
     MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000 ) );
 }
 
+qulonglong MResult::getRowsAffected()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nRowsAffected );
+}
+
 BOOLEAN MResult::isBuffered()
 {
     MYODBCDbgEnter();
@@ -427,6 +436,13 @@
     MYODBCDbgReturn3( "%p", getStatement()->getImpRowDesc() );
 }
 
+STATEMENT_TYPE MResult::getStatementType()
+{
+    MYODBCDbgEnter();
+
+    MYODBCDbgReturn3( "%d", nStatementType );
+}
+
 /*!
     \brief      Gets data based upon the type information in the data source.
 
@@ -628,6 +644,48 @@
     MYODBCDbgReturn( SQL_SUCCESS );
 }
 
+SQLRETURN MResult::setRowsAffected( qulonglong nRowsAffected )
+{
+    MYODBCDbgEnter();
+
+    this->nRowsAffected = nRowsAffected;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MResult::setStatementType( STATEMENT_TYPE nStatementType )
+{
+    MYODBCDbgEnter();
+
+    this->nStatementType = nStatementType;
+
+    MYODBCDbgReturn( SQL_SUCCESS );
+}
+
+SQLRETURN MResult::setStatementType( const QString &stringStatement )
+{
+    MYODBCDbgEnter();
+
+    /*!
+        \internal
+        \todo
+
+        Make this smarter.
+    */
+    if ( stringStatement.startsWith( "SELECT ", Qt::CaseInsensitive ) )
+        MYODBCDbgReturn( setStatementType( STATEMENT_TYPE_SELECT ) );
+    else if ( stringStatement.startsWith( "SHOW ", Qt::CaseInsensitive ) )
+        MYODBCDbgReturn( setStatementType( STATEMENT_TYPE_SHOW ) );
+    else if ( stringStatement.startsWith( "UPDATE ", Qt::CaseInsensitive ) )
+        MYODBCDbgReturn( setStatementType( STATEMENT_TYPE_UPDATE ) );
+    else if ( stringStatement.startsWith( "DELETE ", Qt::CaseInsensitive ) )
+        MYODBCDbgReturn( setStatementType( STATEMENT_TYPE_DELETE ) );
+    else if ( stringStatement.startsWith( "INSERT ", Qt::CaseInsensitive ) )
+        MYODBCDbgReturn( setStatementType( STATEMENT_TYPE_INSERT ) );
+
+    MYODBCDbgReturn( setStatementType( STATEMENT_TYPE_OTHER ) );
+}
+
 /*!
     \brief      Get character column data from current row. 
 

Modified: MYSQLPlus/MYSQLPlusLib/MResult.h
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResult.h	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MResult.h	2006-05-26 23:21:48 UTC (rev 274)
@@ -70,6 +70,26 @@
         STATE_EXECUTED
     };
 
+    /*!
+        \internal
+        \brief      The basic statement type.
+
+        This information is gleaned from the first bit of the statement during a
doPrepare(). It
+        is useful to keep such information - look for usage in the source to see why.
+    */
+    enum STATMENT_TYPE
+    {
+        STATEMENT_TYPE_NULL,        /*!< we do not have a statement                   
                     */
+        STATEMENT_TYPE_MULTI,       /*!< multiple statements, possibly a mix of types,
has been prepared    */
+        STATEMENT_TYPE_SELECT,      /*!< a single SELECT statement has been prepared  
                     */
+        STATEMENT_TYPE_SHOW,        /*!< a single SHOW statement has been prepared    
                     */
+        STATEMENT_TYPE_UPDATE,      /*!< a single UPDATE statement has been prepared  
                     */
+        STATEMENT_TYPE_DELETE,      /*!< a single DELETE statement has been prepared  
                     */
+        STATEMENT_TYPE_INSERT,      /*!< a single INSERT statement has been prepared  
                     */
+        STATEMENT_TYPE_PLUS,        /*!< resultset produced for a catalog function or
other MResultPlus func*/
+        STATEMENT_TYPE_OTHER        /*!< unhandled statement type (treat like
STATEMENT_TYPE_MULTI)         */
+    };
+
     MResult( MStatement *pStatement );
     virtual ~MResult();
 
@@ -80,11 +100,13 @@
     /* getters */
     STATE getState();
 
-    virtual SQLRETURN getColumns( uint *pnColumns ) = 0;
-    virtual SQLRETURN getData( SQLUSMALLINT nColumn, QVariant &variantData ) = 0;
-    virtual SQLRETURN getData( SQLUSMALLINT nColumn, SQLSMALLINT nTargetType, SQLPOINTER
pTargetValue, SQLINTEGER nBufferLength, SQLINTEGER *pnLength, SQLINTEGER *pnIndicator );
-    virtual SQLRETURN getRow( qulonglong *pnRow ) = 0;
-    virtual SQLRETURN getRows( qulonglong *pnRows ) = 0;
+    virtual SQLRETURN   getColumns( uint *pnColumns ) = 0;
+    virtual SQLRETURN   getData( SQLUSMALLINT nColumn, QVariant &variantData ) = 0;
+    virtual SQLRETURN   getData( SQLUSMALLINT nColumn, SQLSMALLINT nTargetType,
SQLPOINTER pTargetValue, SQLINTEGER nBufferLength, SQLINTEGER *pnLength, SQLINTEGER
*pnIndicator );
+    virtual SQLRETURN   getRow( qulonglong *pnRow ) = 0;
+    virtual SQLRETURN   getRows( qulonglong *pnRows ) = 0;
+    qulonglong          getRowsAffected();
+    STATEMENT_TYPE      getStatementType();
 
     /* doers */
     virtual SQLRETURN doAppend() = 0;
@@ -127,6 +149,9 @@
 
     /* support for getData: this is called when target C type is SQL_C_DEFAULT  (derive
type from IRD)  */
     SQLRETURN       setGetDataDefault();
+    SQLRETURN       setRowsAffected( qulonglong nRowsAffected );
+    SQLRETURN       setStatementType( STATEMENT_TYPE nStatementType );
+    SQLRETURN       setStatementType( const QString &stringStatement );
 
     /* support for getData: these enforce ODBC rules generalized based upon SQL type (ie
see "SQL to C: Character" in odbc spec) */
     SQLRETURN       fromCharacterSQL();
@@ -163,8 +188,10 @@
     virtual SQLRETURN doStateRollBack( STATE nState ) = 0;
 
 private:
-    STATE   nState;         /*!< our state                                            
                                                     */
-    BOOLEAN bBuffered;      /*!< true causes entire resultset to get pulled to client
at execute (enabling other features) (default=true)   */
+    STATE           nState;         /*!< our state                                    
                                                                 */
+    BOOLEAN         bBuffered;      /*!< true causes entire resultset to get pulled to
client at execute (enabling other features) (default=true)       */
+    qulonglong      nRowsAffected;  /*!< number of rows affected by a non-SELECT
statement (catalog and SHOW statements count as SELECT in this case)   */
+    STATMENT_TYPE   nStatementType;
 };
 
 #endif

Modified: MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MResultPlus.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -5,7 +5,8 @@
 {
     MYODBCDbgEnter();
 
-    nRow    = 0;
+    nRow            = 0;
+    nStatementType  = STATEMENT_TYPE_PLUS;
     setState( STATE_INITIALIZED );
 
     MYODBCDbgReturn2();
@@ -479,6 +480,27 @@
             MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY004, 0,
NULL ) );
     }
 
+    /*!
+        \internal ODBC RULE
+
+        When SQLExecute, SQLExecDirect, SQLBulkOperations, SQLSetPos, or SQLMoreResults
is called, the SQL_DIAG_ROW_COUNT 
+        field of the diagnostic data structure is set to the row count, and the row count
is cached in an implementation-dependent 
+        way. SQLRowCount returns the cached row count value. The cached row count value
is valid until the statement handle is set 
+        back to the prepared or allocated state, the statement is reexecuted, or
SQLCloseCursor is called. Note that if a function 
+        has been called since the SQL_DIAG_ROW_COUNT field was set, the value returned by
SQLRowCount might be different from the 
+        value in the SQL_DIAG_ROW_COUNT field because the SQL_DIAG_ROW_COUNT field is
reset to 0 by any function call.                
+
+        \internal MYODBC RULE
+
+        Wet set SQL_DIAG_ROW_COUNT when any result set is requested - for example we also
set SQL_DIAG_ROW_COUNT for catalog
+        functions.
+    */
+    qulonglong nRows = -1;
+    if ( !SQL_SUCCEEDED( getRows( &nRows ) ) )
+        getDiagnostic()->setRowCount( -1 );
+    else
+        getDiagnostic()->setRowCount( nRows );
+
     /* we should be at last record so next will make us eof and a subsequent next will be
first record */
     setState( STATE_EXECUTED );
     doNext();
@@ -538,6 +560,7 @@
         case STATE_EXECUTED:
             listResults.clear();
             nRow = 0;
+            nRowsAffected = 0;
             getImpParamDesc()->doClear();
             getImpRowDesc()->doClear();
             resultGetData.doClear();

Modified: MYSQLPlus/MYSQLPlusLib/MResultRes.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultRes.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MResultRes.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -439,6 +439,30 @@
         MYODBCDbgReturn( nReturn );
     }
 
+    /*!
+        \internal ODBC RULE
+
+        When SQLExecute, SQLExecDirect, SQLBulkOperations, SQLSetPos, or SQLMoreResults
is called, the SQL_DIAG_ROW_COUNT 
+        field of the diagnostic data structure is set to the row count, and the row count
is cached in an implementation-dependent 
+        way. SQLRowCount returns the cached row count value. The cached row count value
is valid until the statement handle is set 
+        back to the prepared or allocated state, the statement is reexecuted, or
SQLCloseCursor is called. Note that if a function 
+        has been called since the SQL_DIAG_ROW_COUNT field was set, the value returned by
SQLRowCount might be different from the 
+        value in the SQL_DIAG_ROW_COUNT field because the SQL_DIAG_ROW_COUNT field is
reset to 0 by any function call.                
+
+        \internal MYODBC RULE
+
+        Wet set SQL_DIAG_ROW_COUNT when any result set is requested - for example we also
set SQL_DIAG_ROW_COUNT for catalog
+        functions.
+    */
+    my_ulonglong nAffectedRow = mysql_affected_rows( getMySQL() );
+
+
+    qulonglong nRows = -1;
+    if ( !SQL_SUCCEEDED( getRows( &nRows ) ) )
+        getDiagnostic()->setRowCount( -1 );
+    else
+        getDiagnostic()->setRowCount( nRows );
+
     setState( STATE_EXECUTED );
 
     MYODBCDbgReturn( SQL_SUCCESS );
@@ -638,6 +662,7 @@
     stringStatement             = QString::fromUtf16( psStatement );
     bytearrayStatementTemplate  = stringStatement.toUtf8().data();
 
+    setStatementType( stringStatement );
     setState( STATE_PREPARED );
 
     MYODBCDbgReturn( SQL_SUCCESS );
@@ -878,6 +903,7 @@
             getImpRowDesc()->doClear();
             stringStatement = QString::null;
             bytearrayStatementTemplate.clear();
+            nStatementType = STATEMENT_TYPE_NULL;
             setState(STATE_INITIALIZED );
             break;
 
@@ -885,6 +911,7 @@
             mysql_free_result( pRes );
             pRes = NULL;
             nRow = 0;
+            nRowsAffected = 0;
             resultGetData.doClear();
             setState( STATE_PREPARED );
             break;

Modified: MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MResultStmt.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -502,6 +502,28 @@
 
     nRow = 0; /* eof/bof */
 
+    /*!
+        \internal ODBC RULE
+
+        When SQLExecute, SQLExecDirect, SQLBulkOperations, SQLSetPos, or SQLMoreResults
is called, the SQL_DIAG_ROW_COUNT 
+        field of the diagnostic data structure is set to the row count, and the row count
is cached in an implementation-dependent 
+        way. SQLRowCount returns the cached row count value. The cached row count value
is valid until the statement handle is set 
+        back to the prepared or allocated state, the statement is reexecuted, or
SQLCloseCursor is called. Note that if a function 
+        has been called since the SQL_DIAG_ROW_COUNT field was set, the value returned by
SQLRowCount might be different from the 
+        value in the SQL_DIAG_ROW_COUNT field because the SQL_DIAG_ROW_COUNT field is
reset to 0 by any function call.                
+
+        \internal MYODBC RULE
+
+        Wet set SQL_DIAG_ROW_COUNT when any result set is requested - for example we also
set SQL_DIAG_ROW_COUNT for catalog
+        functions.
+    */
+    mysql_affected_rows(MYSQL *mysql)
+    qulonglong nRows = -1;
+    if ( !SQL_SUCCEEDED( getRows( &nRows ) ) )
+        getDiagnostic()->setRowCount( -1 );
+    else
+        getDiagnostic()->setRowCount( nRows );
+
     setState( STATE_EXECUTED );
 
     MYODBCDbgReturn( SQL_SUCCESS );
@@ -726,6 +748,7 @@
     if ( mysql_stmt_prepare( pstm, stringStatement.toUtf8().data(),
stringStatement.length() ) )
         MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
 
+    setStatementType( stringStatement );
     setState( STATE_PREPARED );
 
     /* get result-set meta-data */
@@ -1005,13 +1028,15 @@
                 getImpParamDesc()->doClear();
                 getImpRowDesc()->doClear();
             }
-            setState(STATE_INITIALIZED );
+            nStatementType = STATEMENT_TYPE_NULL;
+            setState( STATE_INITIALIZED );
             break;
 
         case STATE_EXECUTED:
             if ( !mysql_stmt_reset( pstm ) )
                 MYODBCDbgReturn( getDiagnostic()->doAppend( MDiagnostic::DIA_HY000,
mysql_stmt_errno( pstm ), mysql_stmt_error( pstm ) ) );
             nRow = 0;
+            nRowsAffected = 0;
             resultGetData.doClear();
             setState( STATE_PREPARED );
             break;

Modified: MYSQLPlus/MYSQLPlusLib/MStatement.cpp
===================================================================
--- MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-05-26 18:25:45 UTC (rev 273)
+++ MYSQLPlus/MYSQLPlusLib/MStatement.cpp	2006-05-26 23:21:48 UTC (rev 274)
@@ -1951,7 +1951,23 @@
         pResult = NULL;
     }
 
-    setState( STATE_S3 );
+    switch ( pResult->getStatementType() )
+    {
+        case STATEMENT_TYPE_UPDATE:
+        case STATEMENT_TYPE_DELETE:
+        case STATEMENT_TYPE_INSERT:
+            setState( STATE_S2 );
+            break;
+        case STATEMENT_TYPE_NULL:
+            pDiagnostic->doAppend( MDiagnostic::DIA_01000, 0, tr("STATEMENT_TYPE_NULL
should not happen here") );
+        case STATEMENT_TYPE_MULTI:
+        case STATEMENT_TYPE_SELECT:
+        case STATEMENT_TYPE_SHOW:
+        case STATEMENT_TYPE_PLUS:
+        case STATEMENT_TYPE_OTHER:
+            setState( STATE_S3 );
+            break;
+    }
 
     MYODBCDbgReturn( nReturn );
 }
@@ -2012,7 +2028,7 @@
     MYODBCDbgReturn( SQL_ERROR );
 }
 
-SQLRETURN MStatement::doRowCount( SQLINTEGER *pnRowCountPtr )
+SQLRETURN MStatement::doRowCount( SQLINTEGER *pnRowCount )
 {
     MYODBCDbgEnter();
 
@@ -2020,10 +2036,53 @@
         \internal ODBC RULE
 
         We clear diagnostic each time an ODBC API call is made (with exceptions).
+
+        \note
+
+        We can do this with this func because we are not going to get value from
+        diagnostic header but rather from our cached, internal, value.
     */
     pDiagnostic->doClear();
 
-    MYODBCDbgReturn( SQL_ERROR );
+    if ( !pnRowCount )
+        MYODBCDbgReturn( getDiagnotic()->doAppend( MDiagnostic::DIA_HY000, 0,
tr("pnRowCount must not be null") ) );
+
+    /*!
+        \internal ODBC RULE
+
+        If the last SQL statement executed on the statement handle was not an UPDATE,
INSERT, 
+        or DELETE statement or if the Operation argument in the previous call to
SQLBulkOperations 
+        was not SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK, or if the
Operation 
+        argument in the previous call to SQLSetPos was not SQL_UPDATE or SQL_DELETE, the
value of 
+        *RowCountPtr is driver-defined. 
+
+        \internal MYODBC RULE
+
+        We return the number of resultset rows for SELECT type statements - but this will
be -1
+        when we can not do this at this time (unbuffered results for example).
+    */
+    switch ( pResult->getStatementType() )
+    {
+        case STATEMENT_TYPE_UPDATE:
+        case STATEMENT_TYPE_DELETE:
+        case STATEMENT_TYPE_INSERT:
+            *pnRowCount = getRowsAffected();
+            MYODBCDbgReturn( SQL_SUCCESS );
+        case STATEMENT_TYPE_NULL:
+            pDiagnostic->doAppend( MDiagnostic::DIA_01000, 0, tr("STATEMENT_TYPE_NULL
should not happen here") );
+        case STATEMENT_TYPE_MULTI:
+        case STATEMENT_TYPE_SELECT:
+        case STATEMENT_TYPE_SHOW:
+        case STATEMENT_TYPE_PLUS:
+        case STATEMENT_TYPE_OTHER:
+            if ( pResult->getRows( pnRowCount ) == SQL_SUCCESS )
+                MYODBCDbgReturn( SQL_SUCCESS );
+            break;
+    }
+
+    *pnRowCount = -1;
+
+    MYODBCDbgReturn( SQL_SUCCESS_WITH_INFO );
 }
 
 SQLRETURN MStatement::doSpecialColumns( SQLSMALLINT nIdentifierType, SQLWCHAR
*psCatalogName, SQLSMALLINT nNameLength1, SQLWCHAR *psSchemaName, SQLSMALLINT
nNameLength2, SQLWCHAR *psTableName, SQLSMALLINT nNameLength3, SQLSMALLINT nScope,
SQLSMALLINT nNullable )
@@ -2999,7 +3058,23 @@
         case STATE_S11:
         case STATE_S12:
             pResult->doStateRollBack( MResult::STATE_PREPARED );
-            setState( STATE_S2 );
+            switch ( pResult->getStatementType() )
+            {
+                case STATEMENT_TYPE_UPDATE:
+                case STATEMENT_TYPE_DELETE:
+                case STATEMENT_TYPE_INSERT:
+                    setState( STATE_S2 );
+                    break;
+                case STATEMENT_TYPE_NULL:
+                    pDiagnostic->doAppend( MDiagnostic::DIA_01000, 0,
tr("STATEMENT_TYPE_NULL should not happen here") );
+                case STATEMENT_TYPE_MULTI:
+                case STATEMENT_TYPE_SELECT:
+                case STATEMENT_TYPE_SHOW:
+                case STATEMENT_TYPE_PLUS:
+                case STATEMENT_TYPE_OTHER:
+                    setState( STATE_S3 );
+                    break;
+            }
             break;
 
         default:

Thread
Connector/ODBC 5 commit: r274 - MYSQLPlus/MYSQLPlusLibpharvey27 May