Addressed various issues with PHP 7.4 beta1 (#1015)

This commit is contained in:
Jenny Tam 2019-07-29 08:02:50 -07:00 committed by GitHub
parent 1a2b49393c
commit 65daa7a481
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 168 additions and 146 deletions

View file

@ -1129,11 +1129,11 @@ int pdo_sqlsrv_stmt_get_col_meta( _Inout_ pdo_stmt_t *stmt, _In_ zend_long colno
} }
} }
catch( core::CoreException& ) { catch( core::CoreException& ) {
zval_ptr_dtor(return_value);
return FAILURE; return FAILURE;
} }
catch(...) { catch(...) {
zval_ptr_dtor(return_value);
DIE( "pdo_sqlsrv_stmt_get_col_meta: Unknown exception occurred while retrieving metadata." ); DIE( "pdo_sqlsrv_stmt_get_col_meta: Unknown exception occurred while retrieving metadata." );
} }

View file

@ -988,7 +988,7 @@ void core_sqlsrv_sensitivity_metadata( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
return; return;
} }
if (stmt->current_sensitivity_metadata != NULL) { if (stmt->current_sensitivity_metadata) {
// Already cached, so return // Already cached, so return
return; return;
} }
@ -1873,7 +1873,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
// be returned as a zval. // be returned as a zval.
case SQLSRV_PHPTYPE_DATETIME: case SQLSRV_PHPTYPE_DATETIME:
{ {
char* field_value_temp = NULL; sqlsrv_malloc_auto_ptr<char> field_value_temp;
SQLLEN field_len_temp = 0; SQLLEN field_len_temp = 0;
field_value_temp = static_cast<char*>(sqlsrv_malloc(MAX_DATETIME_STRING_LEN)); field_value_temp = static_cast<char*>(sqlsrv_malloc(MAX_DATETIME_STRING_LEN));
@ -1882,8 +1882,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
SQLRETURN r = stmt->current_results->get_data(field_index + 1, SQL_C_CHAR, field_value_temp, MAX_DATETIME_STRING_LEN, &field_len_temp, true TSRMLS_CC); SQLRETURN r = stmt->current_results->get_data(field_index + 1, SQL_C_CHAR, field_value_temp, MAX_DATETIME_STRING_LEN, &field_len_temp, true TSRMLS_CC);
if (r == SQL_NO_DATA || field_len_temp == SQL_NULL_DATA) { if (r == SQL_NO_DATA || field_len_temp == SQL_NULL_DATA) {
sqlsrv_free(field_value_temp); field_value_temp.reset();
field_value_temp = NULL;
field_len_temp = 0; field_len_temp = 0;
} }
@ -1892,6 +1891,7 @@ void core_get_field_common( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT field_i
} }
field_value = field_value_temp; field_value = field_value_temp;
field_value_temp.transferred();
*field_len = field_len_temp; *field_len = field_len_temp;
break; break;
@ -2420,142 +2420,151 @@ void format_decimal_numbers(_In_ SQLSMALLINT decimals_places, _In_ SQLSMALLINT f
void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC ) void finalize_output_parameters( _Inout_ sqlsrv_stmt* stmt TSRMLS_DC )
{ {
if( Z_ISUNDEF(stmt->output_params) ) if (Z_ISUNDEF(stmt->output_params))
return; return;
HashTable* params_ht = Z_ARRVAL( stmt->output_params ); HashTable* params_ht = Z_ARRVAL(stmt->output_params);
zend_ulong index = -1; zend_ulong index = -1;
zend_string* key = NULL; zend_string* key = NULL;
void* output_param_temp = NULL; void* output_param_temp = NULL;
ZEND_HASH_FOREACH_KEY_PTR( params_ht, index, key, output_param_temp ) { try {
sqlsrv_output_param* output_param = static_cast<sqlsrv_output_param*>( output_param_temp ); ZEND_HASH_FOREACH_KEY_PTR(params_ht, index, key, output_param_temp)
zval* value_z = Z_REFVAL_P( output_param->param_z );
switch( Z_TYPE_P( value_z )) {
case IS_STRING:
{ {
// adjust the length of the string to the value returned by SQLBindParameter in the ind_ptr parameter sqlsrv_output_param* output_param = static_cast<sqlsrv_output_param*>(output_param_temp);
char* str = Z_STRVAL_P( value_z ); zval* value_z = Z_REFVAL_P(output_param->param_z);
SQLLEN str_len = stmt->param_ind_ptrs[output_param->param_num]; switch (Z_TYPE_P(value_z)) {
if( str_len == 0 ) { case IS_STRING:
core::sqlsrv_zval_stringl( value_z, "", 0 );
continue;
}
if( str_len == SQL_NULL_DATA ) {
zend_string_release( Z_STR_P( value_z ));
ZVAL_NULL( value_z );
continue;
}
// if there was more to output than buffer size to hold it, then throw a truncation error
int null_size = 0;
switch( output_param->encoding ) {
case SQLSRV_ENCODING_UTF8:
null_size = sizeof( SQLWCHAR ); // string isn't yet converted to UTF-8, still UTF-16
break;
case SQLSRV_ENCODING_SYSTEM:
null_size = 1;
break;
case SQLSRV_ENCODING_BINARY:
null_size = 0;
break;
default:
SQLSRV_ASSERT( false, "Invalid encoding in output_param structure." );
break;
}
CHECK_CUSTOM_ERROR( str_len > ( output_param->original_buffer_len - null_size ), stmt,
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED, output_param->param_num + 1 ) {
throw core::CoreException();
}
// For ODBC 11+ see https://msdn.microsoft.com/en-us/library/jj219209.aspx
// A length value of SQL_NO_TOTAL for SQLBindParameter indicates that the buffer contains up to
// output_param->original_buffer_len data and is NULL terminated.
// The IF statement can be true when using connection pooling with unixODBC 2.3.4.
if ( str_len == SQL_NO_TOTAL )
{ {
str_len = output_param->original_buffer_len - null_size; // adjust the length of the string to the value returned by SQLBindParameter in the ind_ptr parameter
} char* str = Z_STRVAL_P(value_z);
SQLLEN str_len = stmt->param_ind_ptrs[output_param->param_num];
if (output_param->encoding == SQLSRV_ENCODING_BINARY) { if (str_len == 0) {
// ODBC doesn't null terminate binary encodings, but PHP complains if a string isn't null terminated core::sqlsrv_zval_stringl(value_z, "", 0);
// so we do that here if the length of the returned data is less than the original allocation. The continue;
// original allocation null terminates the buffer already.
if (str_len < output_param->original_buffer_len) {
str[str_len] = '\0';
} }
core::sqlsrv_zval_stringl(value_z, str, str_len); if (str_len == SQL_NULL_DATA) {
} zend_string_release(Z_STR_P(value_z));
else { ZVAL_NULL(value_z);
param_meta_data metaData = output_param->getMetaData(); continue;
if (output_param->encoding != SQLSRV_ENCODING_CHAR) {
char* outString = NULL;
SQLLEN outLen = 0;
bool result = convert_string_from_utf16(output_param->encoding, reinterpret_cast<const SQLWCHAR*>(str), int(str_len / sizeof(SQLWCHAR)), &outString, outLen );
CHECK_CUSTOM_ERROR(!result, stmt, SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE, get_last_error_message()) {
throw core::CoreException();
}
if (stmt->format_decimals && (metaData.sql_type == SQL_DECIMAL || metaData.sql_type == SQL_NUMERIC)) {
format_decimal_numbers(NO_CHANGE_DECIMAL_PLACES, metaData.decimal_digits, outString, &outLen);
}
core::sqlsrv_zval_stringl(value_z, outString, outLen);
sqlsrv_free(outString);
} }
else {
if (stmt->format_decimals && (metaData.sql_type == SQL_DECIMAL || metaData.sql_type == SQL_NUMERIC)) {
format_decimal_numbers(NO_CHANGE_DECIMAL_PLACES, metaData.decimal_digits, str, &str_len);
}
// if there was more to output than buffer size to hold it, then throw a truncation error
int null_size = 0;
switch (output_param->encoding) {
case SQLSRV_ENCODING_UTF8:
null_size = sizeof(SQLWCHAR); // string isn't yet converted to UTF-8, still UTF-16
break;
case SQLSRV_ENCODING_SYSTEM:
null_size = 1;
break;
case SQLSRV_ENCODING_BINARY:
null_size = 0;
break;
default:
SQLSRV_ASSERT(false, "Invalid encoding in output_param structure.");
break;
}
CHECK_CUSTOM_ERROR(str_len > (output_param->original_buffer_len - null_size), stmt,
SQLSRV_ERROR_OUTPUT_PARAM_TRUNCATED, output_param->param_num + 1)
{
throw core::CoreException();
}
// For ODBC 11+ see https://msdn.microsoft.com/en-us/library/jj219209.aspx
// A length value of SQL_NO_TOTAL for SQLBindParameter indicates that the buffer contains up to
// output_param->original_buffer_len data and is NULL terminated.
// The IF statement can be true when using connection pooling with unixODBC 2.3.4.
if (str_len == SQL_NO_TOTAL) {
str_len = output_param->original_buffer_len - null_size;
}
if (output_param->encoding == SQLSRV_ENCODING_BINARY) {
// ODBC doesn't null terminate binary encodings, but PHP complains if a string isn't null terminated
// so we do that here if the length of the returned data is less than the original allocation. The
// original allocation null terminates the buffer already.
if (str_len < output_param->original_buffer_len) {
str[str_len] = '\0';
}
core::sqlsrv_zval_stringl(value_z, str, str_len); core::sqlsrv_zval_stringl(value_z, str, str_len);
} }
} else {
} param_meta_data metaData = output_param->getMetaData();
break;
case IS_LONG: if (output_param->encoding != SQLSRV_ENCODING_CHAR) {
// for a long or a float, simply check if NULL was returned and set the parameter to a PHP null if so char* outString = NULL;
if( stmt->param_ind_ptrs[output_param->param_num] == SQL_NULL_DATA ) { SQLLEN outLen = 0;
ZVAL_NULL( value_z ); bool result = convert_string_from_utf16(output_param->encoding, reinterpret_cast<const SQLWCHAR*>(str), int(str_len / sizeof(SQLWCHAR)), &outString, outLen);
} CHECK_CUSTOM_ERROR(!result, stmt, SQLSRV_ERROR_OUTPUT_PARAM_ENCODING_TRANSLATE, get_last_error_message())
else if( output_param->is_bool ) { {
convert_to_boolean( value_z ); throw core::CoreException();
} }
else {
ZVAL_LONG( value_z, static_cast<int>( Z_LVAL_P( value_z ))); if (stmt->format_decimals && (metaData.sql_type == SQL_DECIMAL || metaData.sql_type == SQL_NUMERIC)) {
} format_decimal_numbers(NO_CHANGE_DECIMAL_PLACES, metaData.decimal_digits, outString, &outLen);
break; }
case IS_DOUBLE:
// for a long or a float, simply check if NULL was returned and set the parameter to a PHP null if so core::sqlsrv_zval_stringl(value_z, outString, outLen);
if (stmt->param_ind_ptrs[output_param->param_num] == SQL_NULL_DATA) { sqlsrv_free(outString);
ZVAL_NULL(value_z); }
} else {
else if (output_param->php_out_type == SQLSRV_PHPTYPE_INT) { if (stmt->format_decimals && (metaData.sql_type == SQL_DECIMAL || metaData.sql_type == SQL_NUMERIC)) {
// first check if its value is out of range format_decimal_numbers(NO_CHANGE_DECIMAL_PLACES, metaData.decimal_digits, str, &str_len);
double dval = Z_DVAL_P(value_z); }
if (dval > INT_MAX || dval < INT_MIN) {
CHECK_CUSTOM_ERROR(true, stmt, SQLSRV_ERROR_DOUBLE_CONVERSION_FAILED) { core::sqlsrv_zval_stringl(value_z, str, str_len);
throw core::CoreException();
} }
} }
// if the output param is a boolean, still convert to
// a long integer first to take care of rounding
convert_to_long(value_z);
if (output_param->is_bool) {
convert_to_boolean(value_z);
}
} }
break; break;
default: case IS_LONG:
DIE( "Illegal or unknown output parameter type. This should have been caught in core_sqlsrv_bind_parameter." ); // for a long or a float, simply check if NULL was returned and set the parameter to a PHP null if so
break; if (stmt->param_ind_ptrs[output_param->param_num] == SQL_NULL_DATA) {
} ZVAL_NULL(value_z);
value_z = NULL; }
} ZEND_HASH_FOREACH_END(); else if (output_param->is_bool) {
convert_to_boolean(value_z);
}
else {
ZVAL_LONG(value_z, static_cast<int>(Z_LVAL_P(value_z)));
}
break;
case IS_DOUBLE:
// for a long or a float, simply check if NULL was returned and set the parameter to a PHP null if so
if (stmt->param_ind_ptrs[output_param->param_num] == SQL_NULL_DATA) {
ZVAL_NULL(value_z);
}
else if (output_param->php_out_type == SQLSRV_PHPTYPE_INT) {
// first check if its value is out of range
double dval = Z_DVAL_P(value_z);
if (dval > INT_MAX || dval < INT_MIN) {
CHECK_CUSTOM_ERROR(true, stmt, SQLSRV_ERROR_DOUBLE_CONVERSION_FAILED)
{
throw core::CoreException();
}
}
// if the output param is a boolean, still convert to
// a long integer first to take care of rounding
convert_to_long(value_z);
if (output_param->is_bool) {
convert_to_boolean(value_z);
}
}
break;
default:
DIE("Illegal or unknown output parameter type. This should have been caught in core_sqlsrv_bind_parameter.");
break;
}
value_z = NULL;
} ZEND_HASH_FOREACH_END();
}
catch (core::CoreException&) {
// empty the hash table due to exception caught
zend_hash_clean(Z_ARRVAL(stmt->output_params));
throw;
}
// empty the hash table since it's been processed // empty the hash table since it's been processed
zend_hash_clean( Z_ARRVAL( stmt->output_params )); zend_hash_clean(Z_ARRVAL(stmt->output_params));
return; return;
} }

View file

@ -44,7 +44,11 @@ int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ TSRMLS
// read from a sqlsrv stream into the buffer provided by Zend. The parameters for binary vs. char are // read from a sqlsrv stream into the buffer provided by Zend. The parameters for binary vs. char are
// set when sqlsrv_get_field is called by the user specifying which field type they want. // set when sqlsrv_get_field is called by the user specifying which field type they want.
size_t sqlsrv_stream_read( _Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count TSRMLS_DC ) #if PHP_VERSION_ID >= 70400
ssize_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count TSRMLS_DC)
#else
size_t sqlsrv_stream_read(_Inout_ php_stream* stream, _Out_writes_bytes_(count) char* buf, _Inout_ size_t count TSRMLS_DC)
#endif
{ {
SQLLEN read = 0; SQLLEN read = 0;
SQLSMALLINT c_type = SQL_C_CHAR; SQLSMALLINT c_type = SQL_C_CHAR;
@ -184,15 +188,20 @@ size_t sqlsrv_stream_read( _Inout_ php_stream* stream, _Out_writes_bytes_(count)
return static_cast<size_t>( read ); return static_cast<size_t>( read );
} }
catch (core::CoreException&) {
catch( core::CoreException& ) { #if PHP_VERSION_ID >= 70400
return -1;
#else
return 0; return 0;
#endif
} }
catch( ... ) { catch (...) {
LOG(SEV_ERROR, "sqlsrv_stream_read: Unknown exception caught.");
LOG( SEV_ERROR, "sqlsrv_stream_read: Unknown exception caught." ); #if PHP_VERSION_ID >= 70400
return -1;
#else
return 0; return 0;
#endif
} }
} }

View file

@ -24,6 +24,6 @@ if ($c !== false) {
Fatal error: Uncaught PDOException: SQLSTATE\[(28000|08001|HYT00)\]: .*\[Microsoft\]\[ODBC Driver 1[0-9] for SQL Server\](\[SQL Server\])?(Named Pipes Provider: Could not open a connection to SQL Server \[2\]\. |TCP Provider: Error code (0x2726|0x2AF9)|Login timeout expired|Login failed for user 'sa'\.) in .+(\/|\\)pdo_utf8_conn\.php:[0-9]+ Fatal error: Uncaught PDOException: SQLSTATE\[(28000|08001|HYT00)\]: .*\[Microsoft\]\[ODBC Driver 1[0-9] for SQL Server\](\[SQL Server\])?(Named Pipes Provider: Could not open a connection to SQL Server \[2\]\. |TCP Provider: Error code (0x2726|0x2AF9)|Login timeout expired|Login failed for user 'sa'\.) in .+(\/|\\)pdo_utf8_conn\.php:[0-9]+
Stack trace: Stack trace:
#0 .+(\/|\\)pdo_utf8_conn\.php\([0-9]+\): PDO->__construct\('sqlsrv:Server=l\.\.\.', 'sa', 'Sunshine4u'\) #0 .+(\/|\\)pdo_utf8_conn\.php\([0-9]+\): PDO->__construct(\(\)|\('sqlsrv:Server=l\.\.\.', 'sa', 'Sunshine4u'\))
#1 {main} #1 {main}
thrown in .+(\/|\\)pdo_utf8_conn\.php on line [0-9]+ thrown in .+(\/|\\)pdo_utf8_conn\.php on line [0-9]+

View file

@ -431,6 +431,6 @@ Test_9 : FETCH_INVALID :
Fatal error: Uncaught Error: Undefined class constant 'FETCH_UNKNOWN' in %s:%x Fatal error: Uncaught Error: Undefined class constant 'FETCH_UNKNOWN' in %s:%x
Stack trace: Stack trace:
#0 %s: fetchAllInvalid(Object(PDO), 'PDO_MainTypes') #0 %s: fetchAllInvalid(%S)
#1 {main} #1 {main}
thrown in %s on line %x thrown in %s on line %x

View file

@ -35,7 +35,7 @@ try {
throw new Exception( "Not A" ); throw new Exception( "Not A" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR ); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR );
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -53,7 +53,7 @@ try {
throw new Exception( "Not A" ); throw new Exception( "Not A" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, -1 ); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, -1 );
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -63,7 +63,7 @@ try {
throw new Exception( "Not C" ); throw new Exception( "Not C" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT ); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT );
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -73,7 +73,7 @@ try {
throw new Exception( "Not C" ); throw new Exception( "Not C" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, 1 ); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, 1 );
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -99,7 +99,7 @@ try {
throw new Exception( "Not A" ); throw new Exception( "Not A" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, -1 ); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_ABS, -1 );
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -125,7 +125,7 @@ try {
throw new Exception( "Not C" ); throw new Exception( "Not C" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT);
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -135,7 +135,7 @@ try {
throw new Exception( "Not A" ); throw new Exception( "Not A" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_PRIOR);
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }
@ -145,7 +145,7 @@ try {
throw new Exception( "Not A" ); throw new Exception( "Not A" );
} }
$row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, -1); $row = $stmt1->fetch( PDO::FETCH_ASSOC, PDO::FETCH_ORI_REL, -1);
if( $row[ 'val' ] != false ) { if ($row !== false) {
throw new Exception( "Not false" ); throw new Exception( "Not false" );
} }

View file

@ -257,6 +257,6 @@ Test_9 : FETCH_INVALID :
Fatal error: Uncaught Error: Undefined class constant 'FETCH_UNKNOWN' in %s:%x Fatal error: Uncaught Error: Undefined class constant 'FETCH_UNKNOWN' in %s:%x
Stack trace: Stack trace:
#0 %s: fetchWithStyle(Object(PDO), 'PDO_MainTypes', 'PDO::FETCH_INVA...') #0 %s: fetchWithStyle(%S)
#1 {main} #1 {main}
thrown in %s on line %x thrown in %s on line %x

View file

@ -59,7 +59,8 @@ foreach ($dataTypes as $dataType) {
} }
} }
// 22018 is the SQLSTATE for any incompatible conversion errors // 22018 is the SQLSTATE for any incompatible conversion errors
if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) { $errors = sqlsrv_errors();
if (!empty($errors) && $isCompatible && $errors[0]['SQLSTATE'] == 22018) {
echo "$sqlType should be compatible with $dataType\n"; echo "$sqlType should be compatible with $dataType\n";
$success = false; $success = false;
} }

View file

@ -69,7 +69,8 @@ foreach ($dataTypes as $dataType) {
} }
} }
// 22018 is the SQLSTATE for any incompatible conversion errors // 22018 is the SQLSTATE for any incompatible conversion errors
if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) { $errors = sqlsrv_errors();
if (!empty($errors) && $isCompatible && $errors[0]['SQLSTATE'] == 22018) {
echo "$sqlType should be compatible with $dataType\n"; echo "$sqlType should be compatible with $dataType\n";
$success = false; $success = false;
} }

View file

@ -57,7 +57,8 @@ foreach ($dataTypes as $dataType) {
} }
} }
// 22018 is the SQLSTATE for any incompatible conversion errors // 22018 is the SQLSTATE for any incompatible conversion errors
if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) { $errors = sqlsrv_errors();
if (!empty($errors) && $isCompatible && $errors[0]['SQLSTATE'] == 22018) {
echo "$sqlType should be compatible with $dataType\n"; echo "$sqlType should be compatible with $dataType\n";
$success = false; $success = false;
} }

View file

@ -44,7 +44,8 @@ function fetchData($conn, $table, $size)
echo "Expect this to fail\n"; echo "Expect this to fail\n";
} else { } else {
$error = 'Memory limit of 1 KB exceeded for buffered query'; $error = 'Memory limit of 1 KB exceeded for buffered query';
if (strpos(sqlsrv_errors()[0]['message'], $error) === false) { $errors = sqlsrv_errors();
if (!empty($errors) && strpos($errors[0]['message'], $error) === false) {
print_r(sqlsrv_errors()); print_r(sqlsrv_errors());
} }
} }