diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index 03805f64..e6fe5c44 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -1067,17 +1067,22 @@ int pdo_sqlsrv_stmt_next_rowset( _Inout_ pdo_stmt_t *stmt TSRMLS_DC ) SQLSRV_ASSERT( driver_stmt != NULL, "pdo_sqlsrv_stmt_next_rowset: driver_data object was null" ); - // Make sure that we haven't gone past the end of the result set, then make sure that - // the result set is not null. Null means SQLNumResultCols returns 0 and SQLRowCount - // is not > 0. Normally the latter error is handled in core_sqlsrv_fetch(), but if the - // user calls nextRowset() before fetch() the error is never shown so we handle it here. - // In that case, however, core_sqlsrv_has_any_result would return false if we are at - // the end of a non-null result set, so we check for that error first to make sure the - // user gets the correct error message. + // Return the correct error in case the user calls nextRowset() on a null result set. + // Null means that SQLNumResultCols() returns 0 and SQLRowCount is not return > 0. But first + // check that the statement has been executed and that we are not past the end of a non-null + // result set to make sure the user gets the correct error message. These checks are also + // done in core_sqlsrv_next_result(), but we cannot check for null results there because that + // function can be called without calling this one, and SQLSRV_ERROR_NO_FIELDS can then + // be triggered incorrectly. + CHECK_CUSTOM_ERROR( !driver_stmt->executed, driver_stmt, SQLSRV_ERROR_STATEMENT_NOT_EXECUTED ) { + throw core::CoreException(); + } + CHECK_CUSTOM_ERROR( driver_stmt->past_next_result_end, driver_stmt, SQLSRV_ERROR_NEXT_RESULT_PAST_END ) { throw core::CoreException(); } + // Now make sure the result set is not null. bool has_result = core_sqlsrv_has_any_result( driver_stmt ); if(!driver_stmt->fetch_called){ diff --git a/source/sqlsrv/stmt.cpp b/source/sqlsrv/stmt.cpp index 70f93e2c..33acee7a 100644 --- a/source/sqlsrv/stmt.cpp +++ b/source/sqlsrv/stmt.cpp @@ -561,13 +561,17 @@ PHP_FUNCTION( sqlsrv_next_result ) try { - // Make sure that we haven't gone past the end of the result set, then make sure that - // the result set is not null. Null means SQLNumResultCols returns 0 and SQLRowCount - // is not > 0. Normally the latter error is handled in core_sqlsrv_fetch(), but if the - // user calls sqlsrv_next_result() before fetch() the error is never shown so we handle it here. - // In that case, however, core_sqlsrv_has_any_result would return false if we are at - // the end of a non-null result set, so we check for that error first to make sure the - // user gets the correct error message. + // Return the correct error in case the user calls sqlsrv_next_result() on a null result set. + // Null means that SQLNumResultCols() returns 0 and SQLRowCount is not return > 0. But first + // check that the statement has been executed and that we are not past the end of a non-null + // result set to make sure the user gets the correct error message. These checks are also + // done in core_sqlsrv_next_result(), but we cannot check for null results there because that + // function can be called without calling this one, and SQLSRV_ERROR_NO_FIELDS can then + // be triggered incorrectly. + CHECK_CUSTOM_ERROR( !stmt->executed, stmt, SQLSRV_ERROR_STATEMENT_NOT_EXECUTED ) { + throw core::CoreException(); + } + CHECK_CUSTOM_ERROR( stmt->past_next_result_end, stmt, SQLSRV_ERROR_NEXT_RESULT_PAST_END ) { throw core::CoreException(); } diff --git a/test/functional/sqlsrv/sqlsrv_empty_result_error.phpt b/test/functional/sqlsrv/sqlsrv_empty_result_error.phpt index f073d4e5..af0dd2f8 100644 --- a/test/functional/sqlsrv/sqlsrv_empty_result_error.phpt +++ b/test/functional/sqlsrv/sqlsrv_empty_result_error.phpt @@ -68,13 +68,22 @@ Array Array ( [0] => Array + ( + [0] => IMSSP + [SQLSTATE] => IMSSP + [1] => -26 + [code] => -26 + [2] => There are no more results returned by the query. + [message] => There are no more results returned by the query. + ) + [1] => Array ( [0] => HY010 [SQLSTATE] => HY010 [1] => 0 [code] => 0 - [2] => [unixODBC][Driver Manager]Function sequence error - [message] => [unixODBC][Driver Manager]Function sequence error + [2] => [Microsoft][ODBC Driver Manager] Function sequence error + [message] => [Microsoft][ODBC Driver Manager] Function sequence error ) ) diff --git a/test/functional/sqlsrv/test_warning_errors2.phpt b/test/functional/sqlsrv/test_warning_errors2.phpt index 3372ca89..8ee12352 100644 --- a/test/functional/sqlsrv/test_warning_errors2.phpt +++ b/test/functional/sqlsrv/test_warning_errors2.phpt @@ -1,159 +1,168 @@ ---TEST-- -warnings as errors ---SKIPIF-- - ---FILE-- - ---EXPECT-- -Array -( - [0] => Array - ( - [0] => IMSSP - [SQLSTATE] => IMSSP - [1] => -11 - [code] => -11 - [2] => The statement must be executed before results can be retrieved. - [message] => The statement must be executed before results can be retrieved. - ) - -) -Array -( - [0] => Array - ( - [0] => IMSSP - [SQLSTATE] => IMSSP - [1] => -11 - [code] => -11 - [2] => The statement must be executed before results can be retrieved. - [message] => The statement must be executed before results can be retrieved. - ) - -) -Array -( - [0] => Array - ( - [0] => IMSSP - [SQLSTATE] => IMSSP - [1] => -11 - [code] => -11 - [2] => The statement must be executed before results can be retrieved. - [message] => The statement must be executed before results can be retrieved. - ) - -) -Array -( - [0] => Array - ( - [0] => IMSSP - [SQLSTATE] => IMSSP - [1] => -11 - [code] => -11 - [2] => The statement must be executed before results can be retrieved. - [message] => The statement must be executed before results can be retrieved. - ) - -) -Array -( - [0] => IMSSP - [SQLSTATE] => IMSSP - [1] => -11 - [code] => -11 - [2] => The statement must be executed before results can be retrieved. - [message] => The statement must be executed before results can be retrieved. -) -Test successful +--TEST-- +warnings as errors +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Array +( + [0] => Array + ( + [0] => IMSSP + [SQLSTATE] => IMSSP + [1] => -11 + [code] => -11 + [2] => The statement must be executed before results can be retrieved. + [message] => The statement must be executed before results can be retrieved. + ) + +) +Array +( + [0] => Array + ( + [0] => IMSSP + [SQLSTATE] => IMSSP + [1] => -11 + [code] => -11 + [2] => The statement must be executed before results can be retrieved. + [message] => The statement must be executed before results can be retrieved. + ) + +) +Array +( + [0] => Array + ( + [0] => IMSSP + [SQLSTATE] => IMSSP + [1] => -11 + [code] => -11 + [2] => The statement must be executed before results can be retrieved. + [message] => The statement must be executed before results can be retrieved. + ) + +) +Array +( + [0] => Array + ( + [0] => IMSSP + [SQLSTATE] => IMSSP + [1] => -11 + [code] => -11 + [2] => The statement must be executed before results can be retrieved. + [message] => The statement must be executed before results can be retrieved. + ) + [1] => Array + ( + [0] => HY010 + [SQLSTATE] => HY010 + [1] => 0 + [code] => 0 + [2] => [unixODBC][Driver Manager]Function sequence error + [message] => [unixODBC][Driver Manager]Function sequence error + ) + +) +Array +( + [0] => IMSSP + [SQLSTATE] => IMSSP + [1] => -11 + [code] => -11 + [2] => The statement must be executed before results can be retrieved. + [message] => The statement must be executed before results can be retrieved. +) +Test successful