From d87c03f5a80853206475758f438eefe6667d7489 Mon Sep 17 00:00:00 2001 From: v-kaywon Date: Fri, 31 Mar 2017 13:38:57 -0700 Subject: [PATCH] do not check has result if execute returns SQL_NO_DATA --- source/pdo_sqlsrv/pdo_dbh.cpp | 4 ++-- source/pdo_sqlsrv/pdo_stmt.cpp | 14 ++++++++++---- source/shared/core_sqlsrv.h | 17 ++--------------- source/shared/core_stmt.cpp | 3 ++- 4 files changed, 16 insertions(+), 22 deletions(-) diff --git a/source/pdo_sqlsrv/pdo_dbh.cpp b/source/pdo_sqlsrv/pdo_dbh.cpp index 5323058f..c7b7d967 100644 --- a/source/pdo_sqlsrv/pdo_dbh.cpp +++ b/source/pdo_sqlsrv/pdo_dbh.cpp @@ -690,11 +690,11 @@ zend_long pdo_sqlsrv_dbh_do( pdo_dbh_t *dbh, const char *sql, size_t sql_len TSR NULL /*valid_stmt_opts*/, pdo_sqlsrv_handle_stmt_error, &temp_stmt TSRMLS_CC ); driver_stmt->set_func( __FUNCTION__ ); - core_sqlsrv_execute( driver_stmt TSRMLS_CC, sql, static_cast( sql_len ) ); + SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt TSRMLS_CC, sql, static_cast( sql_len ) ); // since the user can give us a compound statement, we return the row count for the last set, and since the row count // isn't guaranteed to be valid until all the results have been fetched, we fetch them all first. - if( core_sqlsrv_has_any_result( driver_stmt TSRMLS_CC )) { + if( execReturn != SQL_NO_DATA && core_sqlsrv_has_any_result( driver_stmt TSRMLS_CC )) { SQLRETURN r = SQL_SUCCESS; diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index 2506960b..bfe25cca 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -552,12 +552,18 @@ int pdo_sqlsrv_stmt_execute(pdo_stmt_t *stmt TSRMLS_DC) query_len = static_cast( stmt->active_query_stringlen ); } - core_sqlsrv_execute( driver_stmt TSRMLS_CC, query, query_len ); + SQLRETURN execReturn = core_sqlsrv_execute( driver_stmt TSRMLS_CC, query, query_len ); - stmt->column_count = core::SQLNumResultCols( driver_stmt TSRMLS_CC ); + if ( execReturn == SQL_NO_DATA ) { + stmt->column_count = 0; + stmt->row_count = 0; + } + else { + stmt->column_count = core::SQLNumResultCols( driver_stmt TSRMLS_CC ); - // return the row count regardless if there are any rows or not - stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC ); + // return the row count regardless if there are any rows or not + stmt->row_count = core::SQLRowCount( driver_stmt TSRMLS_CC ); + } // workaround for a bug in the PDO driver manager. It is fairly simple to crash the PDO driver manager with // the following sequence: diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index dec5d8e6..530d41a6 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1363,7 +1363,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( sqlsrv_conn* conn, driver_stmt_factory stm void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALLINT direction, zval* param_z, SQLSRV_PHPTYPE php_out_type, SQLSRV_ENCODING encoding, SQLSMALLINT sql_type, SQLULEN column_size, SQLSMALLINT decimal_digits TSRMLS_DC ); -void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql = NULL, int sql_len = 0 ); +SQLRETURN core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql = NULL, int sql_len = 0 ); field_meta_data* core_sqlsrv_field_metadata( sqlsrv_stmt* stmt, SQLSMALLINT colno TSRMLS_DC ); bool core_sqlsrv_fetch( sqlsrv_stmt* stmt, SQLSMALLINT fetch_orientation, SQLULEN fetch_offset TSRMLS_DC ); void core_sqlsrv_get_field(sqlsrv_stmt* stmt, SQLUSMALLINT field_index, sqlsrv_phptype sqlsrv_phptype, bool prefer_string, @@ -2041,20 +2041,7 @@ namespace core { SQLSMALLINT num_cols; r = ::SQLNumResultCols( stmt->handle(), &num_cols ); - // Workaround for a bug in unixODBC: after SQLExecDirect returns SQL_NO_DATA, - // r = ::SQLNumResultCols( stmt->handle(), &num_cols ); - // returns r=-1 (SQL_ERROR) and error HY010 (Function sequence error) - // but it should have succeeded with r=0 (SQL_SUCCESS) and no error - // instead of throwing an exception, return 0 if the r=-1, stament has been executed, and has a HY010 error - // (HY010 error should not return if stmt->execute is true) -#ifndef _WIN32 - if ( r == -1 && stmt->executed && stmt->current_results != NULL ) { - sqlsrv_error_auto_ptr error; - error = stmt->current_results->get_diag_rec( 1 ); - if ( strcmp( reinterpret_cast( error->sqlstate ), "HY010" ) == 0 ) - return 0; - } -#endif // !_WIN32 + CHECK_SQL_ERROR_OR_WARNING( r, stmt ) { throw CoreException(); } diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 9dd505ec..53605004 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -657,7 +657,7 @@ void core_sqlsrv_bind_param( sqlsrv_stmt* stmt, SQLUSMALLINT param_num, SQLSMALL // Return: // true if there is data, false if there is not -void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len ) +SQLRETURN core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_len ) { SQLRETURN r; @@ -708,6 +708,7 @@ void core_sqlsrv_execute( sqlsrv_stmt* stmt TSRMLS_DC, const char* sql, int sql_ if ( stmt->send_streams_at_exec ) { zend_hash_clean( Z_ARRVAL( stmt->param_streams )); } + return r; } catch( core::CoreException& e ) {