diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 0c909b449..16ca57110 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1322,10 +1322,11 @@ struct sqlsrv_output_param { SQLUSMALLINT param_num; // used to index into the ind_or_len of the statement SQLLEN original_buffer_len; // used to make sure the returned length didn't overflow the buffer bool is_bool; + bool is_long; // string output param constructor - sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len ) : - param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ) + sqlsrv_output_param( _In_ zval* p_z, _In_ SQLSRV_ENCODING enc, _In_ int num, _In_ SQLUINTEGER buffer_len, _In_ bool is_long ) : + param_z( p_z ), encoding( enc ), param_num( num ), original_buffer_len( buffer_len ), is_bool( false ), is_long( is_long ) { } @@ -1335,7 +1336,8 @@ struct sqlsrv_output_param { encoding( SQLSRV_ENCODING_INVALID ), param_num( num ), original_buffer_len( -1 ), - is_bool( is_bool ) + is_bool( is_bool ), + is_long( false ) { } }; @@ -1431,7 +1433,7 @@ typedef sqlsrv_stmt* (*driver_stmt_factory)( sqlsrv_conn* conn, SQLHANDLE h, err sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stmt_factory stmt_factory, _In_opt_ HashTable* options_ht, _In_opt_ const stmt_option valid_stmt_opts[], _In_ error_callback const err, _In_opt_ void* driver TSRMLS_DC ); void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ); SQLRETURN core_sqlsrv_execute( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC, _In_reads_bytes_(sql_len) const char* sql = NULL, _In_ int sql_len = 0 ); field_meta_data* core_sqlsrv_field_metadata( _Inout_ sqlsrv_stmt* stmt, _In_ SQLSMALLINT colno TSRMLS_DC ); diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 285764b17..23062b8e7 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -342,7 +342,7 @@ sqlsrv_stmt* core_sqlsrv_create_stmt( _Inout_ sqlsrv_conn* conn, _In_ driver_stm // The sql type is given as a hint if the driver provides it. void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_num, _In_ SQLSMALLINT direction, _Inout_ zval* param_z, - _In_ SQLSRV_PHPTYPE php_out_type, _In_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, + _In_ SQLSRV_PHPTYPE php_out_type, _Inout_ SQLSRV_ENCODING encoding, _Inout_ SQLSMALLINT sql_type, _Inout_ SQLULEN column_size, _Inout_ SQLSMALLINT decimal_digits TSRMLS_DC ) { SQLSMALLINT c_type; @@ -384,14 +384,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( zval_was_null || zval_was_bool ) { convert_to_long( param_z ); } - if( zval_was_long ){ - convert_to_string( param_z ); - encoding = SQLSRV_ENCODING_SYSTEM; - match = Z_TYPE_P( param_z ) == IS_STRING; - } - else { - match = Z_TYPE_P(param_z) == IS_LONG; - } + match = Z_TYPE_P( param_z ) == IS_LONG; break; case SQLSRV_PHPTYPE_FLOAT: if( zval_was_null ) { @@ -423,7 +416,13 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ if( direction == SQL_PARAM_OUTPUT ) { switch( php_out_type ) { case SQLSRV_PHPTYPE_INT: - convert_to_long( param_z ); + if( zval_was_long ){ + convert_to_string( param_z ); + encoding = SQLSRV_ENCODING_SYSTEM; + } + else { + convert_to_long( param_z ); + } break; case SQLSRV_PHPTYPE_FLOAT: convert_to_double( param_z ); @@ -559,7 +558,7 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_ buffer, buffer_len TSRMLS_CC ); // save the parameter to be adjusted and/or converted after the results are processed - sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len )); + sqlsrv_output_param output_param( param_ref, encoding, param_num, static_cast( buffer_len ), zval_was_long ); save_output_param_for_later( stmt, output_param TSRMLS_CC ); @@ -2135,6 +2134,15 @@ void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) else { core::sqlsrv_zval_stringl(value_z, str, str_len); } + if ( output_param->is_long ) { + zval* value_z_temp = ( zval * )sqlsrv_malloc( sizeof( zval )); + ZVAL_COPY( value_z_temp, value_z ); + convert_to_double( value_z_temp ); + if ( Z_DVAL_P( value_z_temp ) > INT_MIN && Z_DVAL_P( value_z_temp ) < INT_MAX ) { + convert_to_long( value_z ); + } + sqlsrv_free( value_z_temp ); + } } break; case IS_LONG: