From 10ff344fca84f1393ba809c604395b6ad3006fbd Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Tue, 5 Jun 2018 13:09:51 -0700 Subject: [PATCH 01/32] Fixed the potential error reported by Prefast code analysis --- source/pdo_sqlsrv/pdo_dbh.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/pdo_sqlsrv/pdo_dbh.cpp b/source/pdo_sqlsrv/pdo_dbh.cpp index 48ed3b123..60d03eeb1 100644 --- a/source/pdo_sqlsrv/pdo_dbh.cpp +++ b/source/pdo_sqlsrv/pdo_dbh.cpp @@ -1276,7 +1276,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, try { - char last_insert_id_query[ LAST_INSERT_ID_QUERY_MAX_LEN ]; + char last_insert_id_query[ LAST_INSERT_ID_QUERY_MAX_LEN ] = {'\0'}; if( name == NULL ) { strcpy_s( last_insert_id_query, sizeof( last_insert_id_query ), LAST_INSERT_ID_QUERY ); } @@ -1300,7 +1300,7 @@ char * pdo_sqlsrv_dbh_last_id( _Inout_ pdo_dbh_t *dbh, _In_z_ const char *name, sqlsrv_malloc_auto_ptr wsql_string; unsigned int wsql_len; - wsql_string = utf16_string_from_mbcs_string( SQLSRV_ENCODING_CHAR, reinterpret_cast( last_insert_id_query ), static_cast( strnlen_s( last_insert_id_query )), &wsql_len ); + wsql_string = utf16_string_from_mbcs_string( SQLSRV_ENCODING_CHAR, reinterpret_cast( last_insert_id_query ), sizeof(last_insert_id_query), &wsql_len ); CHECK_CUSTOM_ERROR( wsql_string == 0, driver_stmt, SQLSRV_ERROR_QUERY_STRING_ENCODING_TRANSLATE, get_last_error_message() ) { throw core::CoreException(); From 44d1bb39ba1a09ac730f11aca9c1e3c1c9fdb8ba Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Wed, 6 Jun 2018 13:18:58 -0700 Subject: [PATCH 02/32] Use SQLSRV_ASSERT for checking NULL ptrs --- source/shared/core_results.cpp | 3 ++- source/shared/core_stream.cpp | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/shared/core_results.cpp b/source/shared/core_results.cpp index d5882f2c6..85a4ecdab 100644 --- a/source/shared/core_results.cpp +++ b/source/shared/core_results.cpp @@ -345,7 +345,8 @@ sqlsrv_error* odbc_get_diag_rec( _In_ sqlsrv_stmt* odbc, _In_ SQLSMALLINT record SQLWCHAR wnative_message[ SQL_MAX_ERROR_MESSAGE_LENGTH + 1 ]; SQLINTEGER native_code; SQLSMALLINT wnative_message_len = 0; - + + SQLSRV_ASSERT(odbc != NULL, "odbc_get_diag_rec: sqlsrv_stmt* odbc was null."); SQLRETURN r = SQLGetDiagRecW( SQL_HANDLE_STMT, odbc->handle(), record_number, wsql_state, &native_code, wnative_message, SQL_MAX_ERROR_MESSAGE_LENGTH + 1, &wnative_message_len ); if( !SQL_SUCCEEDED( r ) || r == SQL_NO_DATA ) { diff --git a/source/shared/core_stream.cpp b/source/shared/core_stream.cpp index 5309f0043..3167d1e83 100644 --- a/source/shared/core_stream.cpp +++ b/source/shared/core_stream.cpp @@ -26,7 +26,7 @@ namespace { int sqlsrv_stream_close( _Inout_ php_stream* stream, int /*close_handle*/ TSRMLS_DC ) { sqlsrv_stream* ss = static_cast( stream->abstract ); - SQLSRV_ASSERT( ss != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." ); + SQLSRV_ASSERT( ss != NULL && ss->stmt != NULL, "sqlsrv_stream_close: sqlsrv_stream* ss was null." ); // free the stream resources in the Zend engine php_stream_free( stream, PHP_STREAM_FREE_RELEASE_STREAM ); @@ -52,7 +52,7 @@ size_t sqlsrv_stream_read( _Inout_ php_stream* stream, _Out_writes_bytes_(count) sqlsrv_malloc_auto_ptr temp_buf; sqlsrv_stream* ss = static_cast( stream->abstract ); - SQLSRV_ASSERT( ss != NULL, "sqlsrv_stream_read: sqlsrv_stream* ss is NULL." ); + SQLSRV_ASSERT( ss != NULL && ss->stmt != NULL, "sqlsrv_stream_read: sqlsrv_stream* ss is NULL." ); try { From f6e450b40859b880430eb2b5790659bca83e9281 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Thu, 7 Jun 2018 13:54:35 -0700 Subject: [PATCH 03/32] For these AKV tests check env despite not AE connected --- .../pdo_ae_azure_key_vault_client_secret.phpt | 2 +- .../pdo_ae_azure_key_vault_keywords.phpt | 2 +- .../pdo_ae_azure_key_vault_username_password.phpt | 2 +- test/functional/pdo_sqlsrv/skipif_not_akv.inc | 15 +++++++++++++++ test/functional/sqlsrv/skipif_not_akv.inc | 15 +++++++++++++++ .../sqlsrv_ae_azure_key_vault_client_secret.phpt | 2 +- .../sqlsrv_ae_azure_key_vault_keywords.phpt | 2 +- ...lsrv_ae_azure_key_vault_username_password.phpt | 2 +- 8 files changed, 36 insertions(+), 6 deletions(-) create mode 100644 test/functional/pdo_sqlsrv/skipif_not_akv.inc create mode 100644 test/functional/sqlsrv/skipif_not_akv.inc diff --git a/test/functional/pdo_sqlsrv/pdo_ae_azure_key_vault_client_secret.phpt b/test/functional/pdo_sqlsrv/pdo_ae_azure_key_vault_client_secret.phpt index d523c69bd..a3bae5210 100644 --- a/test/functional/pdo_sqlsrv/pdo_ae_azure_key_vault_client_secret.phpt +++ b/test/functional/pdo_sqlsrv/pdo_ae_azure_key_vault_client_secret.phpt @@ -1,7 +1,7 @@ --TEST-- Test client ID/secret credentials for Azure Key Vault for Always Encrypted. --SKIPIF-- - + --FILE-- + --FILE-- + --FILE-- \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_azure_key_vault_client_secret.phpt b/test/functional/sqlsrv/sqlsrv_ae_azure_key_vault_client_secret.phpt index fd6a11151..0a8b52a8d 100644 --- a/test/functional/sqlsrv/sqlsrv_ae_azure_key_vault_client_secret.phpt +++ b/test/functional/sqlsrv/sqlsrv_ae_azure_key_vault_client_secret.phpt @@ -1,7 +1,7 @@ --TEST-- Test client ID/secret credentials for Azure Key Vault for Always Encrypted. --SKIPIF-- - + --FILE-- + --FILE-- + --FILE-- Date: Fri, 8 Jun 2018 16:00:27 -0700 Subject: [PATCH 04/32] Added the driver option to run functional tests --- test/functional/pdo_sqlsrv/MsCommon.inc | 158 +----------------- .../pdo_sqlsrv/MsCommon_mid-refactor.inc | 11 +- test/functional/pdo_sqlsrv/MsSetup.inc | 4 +- .../pdo_sqlsrv/PDO21_Connection.phpt | 2 +- .../pdo_sqlsrv/pdo_020_bind_params_array.phpt | 2 + .../pdo_sqlsrv/pdo_040_error_information.phpt | 2 + .../pdo_065_construct_persistent.phpt | 2 +- .../pdo_065_construct_prefetch.phpt | 2 +- .../pdo_sqlsrv/pdo_ae_output_param_all.phpt | 1 + test/functional/pdo_sqlsrv/pdo_utf8_conn.phpt | 3 +- test/functional/pdo_sqlsrv/skipif_not_akv.inc | 5 + .../pdo_sqlsrv/test_ae_keys_setup.phpt | 83 +++++---- test/functional/sqlsrv/MsSetup.inc | 4 +- test/functional/sqlsrv/skipif_not_akv.inc | 6 + .../functional/sqlsrv/test_ae_keys_setup.phpt | 39 +++-- 15 files changed, 106 insertions(+), 218 deletions(-) diff --git a/test/functional/pdo_sqlsrv/MsCommon.inc b/test/functional/pdo_sqlsrv/MsCommon.inc index cddfdab9c..b1c479e95 100644 --- a/test/functional/pdo_sqlsrv/MsCommon.inc +++ b/test/functional/pdo_sqlsrv/MsCommon.inc @@ -8,30 +8,6 @@ */ -// -// looks like an additional file (in addition to pdo_test_base.inc) may be needed for these PHPTs -// to be runnable from the MSSQL teams' internal proprietary test running system -// - -function IsAEQualified($conn) -{ - $msodbcsql_ver = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"]; - $msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; - if ($msodbcsql_maj < 17) { - return false; - } - require 'MsSetup.inc'; - if ($daasMode) { - // running against Azure - return true; - } - // if not Azure, check the server version - $server_ver = $conn->getAttribute(PDO::ATTR_SERVER_VERSION); - if (explode('.', $server_ver)[0] < 13) - return false; - return true; -} - // TO BE DELETED function connect($options=array()) { @@ -40,7 +16,7 @@ function connect($options=array()) // simply use $databaseName from MsSetup.inc to facilitate testing in Azure, // which does not support switching databases require 'MsSetup.inc'; - $conn = new PDO( "sqlsrv:Server=$server;database=$databaseName;ConnectionPooling=false;" , $uid, $pwd, $options); + $conn = new PDO( "sqlsrv:Server=$server;database=$databaseName;Driver=$driver;ConnectionPooling=false;" , $uid, $pwd, $options); $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); return $conn; } @@ -58,138 +34,6 @@ function connect($options=array()) } } - -/** - * Connect to the database specified in MsSetup.inc; Column Encryption keywords automatically added when $keystore is not none - * @param string $keywords : string to append to the dsn string in PDO::_construct - * @param array $options : attributes to pass to PDO::_construct - * @param bool $disableCE : flag for disabling column encryption even when keystore is NOT none - * for testing fetching encrypted data when connection column encryption is off - * @return PDO connection object - */ -function ae_connect( $keywords='', $options=array(), $disableCE = false ) -{ - try - { - // simply use $databaseName from MsSetup.inc to facilitate testing in Azure, - // which does not support switching databases - require 'MsSetup.inc'; - $dsn = "sqlsrv:Server=$server;database=$databaseName;ConnectionPooling=false;"; - if ( $keystore != "none" && !$disableCE ) - { - $dsn .= "ColumnEncryption=Enabled;"; - } - if ( $keystore == "ksp" && !$disableCE ) - { - require( 'AE_Ksp.inc' ); - $ksp_path = getKSPPath(); - $dsn .= "CEKeystoreProvider=$ksp_path;CEKeystoreName=$ksp_name;CEKeystoreEncryptKey=$encrypt_key;"; - } - if ( $keywords ) - { - $dsn .= $keywords; - } - $conn = new PDO( $dsn, $uid, $pwd, $options ); - $conn->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION ); - return $conn; - } - catch( PDOException $e ) - { - var_dump( $e ); - exit; - } - catch(Exception $e) - { - var_dump( $e ); - exit; - } -} - - -/** - * @return string CEK name depending on the connection keywords - */ -function getCekName() -{ - require 'MsSetup.inc'; - $cekName = ''; - switch ( $keystore ) { - case "none": - $cekName = ''; - break; - case "win": - $cekName = 'AEColumnKey'; - break; - case "ksp": - $cekName = 'CustomCEK'; - break; - case "akv": - $cekName = 'AKVColumnKey'; - break; - default: - echo "getCekName: Invalid keystore name.\n"; - } - return $cekName; -} - - -/** - * class for encapsulating column metadata needed for creating a table - */ -class columnMeta { - public $colName; - public $dataType; //a string that includes the size of the type if necessary (e.g., decimal(10,5)) - public $encType; //randomized or deterministic; default is deterministic - public $options; //a string that is null by default (e.g. NOT NULL Identity (1,1) ) - - function __construct( $dataType, $colName = null, $options = null, $encType = "deterministic" ) - { - if ( is_null( $colName )) - { - $this->colName = get_default_colname( $dataType ); - } - else - { - $this->colName = $colName; - } - $this->dataType = $dataType; - $this->encType = $encType; - $this->options = $options; - } - /** - * @return string column definition for creating a table - */ - function getColDef() - { - require 'MsSetup.inc'; - $append = " "; - - // an identity column is not encrypted because a select query with identity column as the where clause is often run and the user want to have to bind parameter every time - if ( $keystore != "none" && stripos( $this->options, "identity" ) === false ) - { - $cekName = getCekName(); - if ( stripos( $this->dataType, "char" ) !== false ) - $append .= "COLLATE Latin1_General_BIN2 "; - $append .= sprintf( "ENCRYPTED WITH (ENCRYPTION_TYPE = %s, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = $cekName) ", $this->encType ); - } - $append .= $this->options; - $colDef = "[" . $this->colName . "] " . $this->dataType . $append; - return $colDef; - } -} - - -/** - * @return string default column name when a name is not provided in the columnMeta class - */ -function get_default_colname( $dataType ) -{ - $colName = "c_" . str_replace( ",", "_", str_replace( "(", "_", $dataType )); - $colName = rtrim( $colName, ")" ); - return $colName; -} - - /** * Create a table * @param object $conn : PDO connection object diff --git a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc index dd183c32a..7aa915a0b 100644 --- a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc +++ b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc @@ -13,10 +13,6 @@ // to be runnable from the MSSQL teams' internal proprietary test running system // -const KSP_NAME = 'MyCustomKSPName'; -const ENCRYPT_KEY = 'LPKCWVD07N3RG98J0MBLG4H2'; -const KSP_TEST_TABLE = 'CustomKSPTestTable'; - function isAEQualified($conn) { $msodbcsql_ver = $conn->getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"]; @@ -52,7 +48,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP // simply use $databaseName from MsSetup.inc to facilitate testing in Azure, // which does not support switching databases require("MsSetup.inc"); - $dsn = getDSN($server, $databaseName, $keywords, $disableCE); + $dsn = getDSN($server, $databaseName, $driver, $keywords, $disableCE); $conn = new PDO($dsn, $uid, $pwd, $options); if ($errmode == PDO::ERRMODE_EXCEPTION || $errmode == PDO::ERRMODE_WARNING || $errmode == PDO::ERRMODE_SILENT) { $conn->setAttribute(PDO::ATTR_ERRMODE, $errmode); @@ -76,7 +72,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP * @param bool $disableCE : flag for disabling column encryption even when keystore is NOT none * @return string dsn string used for PDO constructor */ -function getDSN($sqlsrvserver, $database, $keywords = '', $disableCE = false) +function getDSN($sqlsrvserver, $database, $driver, $keywords = '', $disableCE = false) { require("MsSetup.inc"); $dsn = ""; @@ -89,6 +85,9 @@ function getDSN($sqlsrvserver, $database, $keywords = '', $disableCE = false) if ($database) { $dsn .= "database=$database;"; } + if ($driver) { + $dsn .= "driver=$driver;"; + } if ($keystore != "none" && !$disableCE) { $dsn .= "ColumnEncryption=Enabled;"; } diff --git a/test/functional/pdo_sqlsrv/MsSetup.inc b/test/functional/pdo_sqlsrv/MsSetup.inc index e07c46a7d..823f283cc 100644 --- a/test/functional/pdo_sqlsrv/MsSetup.inc +++ b/test/functional/pdo_sqlsrv/MsSetup.inc @@ -18,7 +18,6 @@ if (isset($_ENV['MSSQL_SERVER']) || isset($_ENV['MSSQL_USER']) || isset($_ENV['M $uid = 'TARGET_USERNAME'; $pwd = 'TARGET_PASSWORD'; $databaseName = 'TARGET_DATABASE'; - $DriverName = "ODBC Driver 11 for SQL Server"; } $adServer = 'TARGET_AD_SERVER'; @@ -27,13 +26,12 @@ $adUser = 'TARGET_AD_USERNAME'; $adPassword = 'TARGET_AD_PASSWORD'; $driverType = true; -$PhpDriver = "ODBC Driver 11 for SQL Server"; +$driver = "ODBC Driver 17 for SQL Server"; $tableName = 'pdo_test_table'; $tableIndex = 'php_test_table_idx'; $procName = 'php_test_proc'; $fileName = 'php_test_file.dat'; -$dsn = "odbc:Driver={$DriverName};Server=$server"; $connectionOptions = array(); $daasMode = false; $marsMode = true; diff --git a/test/functional/pdo_sqlsrv/PDO21_Connection.phpt b/test/functional/pdo_sqlsrv/PDO21_Connection.phpt index f09899626..9498a3585 100644 --- a/test/functional/pdo_sqlsrv/PDO21_Connection.phpt +++ b/test/functional/pdo_sqlsrv/PDO21_Connection.phpt @@ -15,7 +15,7 @@ try { // Invalid connection attempt => errors are expected $serverName="InvalidServerName"; - $dsn = getDSN($serverName, $databaseName); + $dsn = getDSN($serverName, $databaseName, $driver); $conn1 = new PDO($dsn, $uid, $pwd, $connectionOptions); if ($conn1) { printf("Invalid connection attempt should have failed.\n"); diff --git a/test/functional/pdo_sqlsrv/pdo_020_bind_params_array.phpt b/test/functional/pdo_sqlsrv/pdo_020_bind_params_array.phpt index 577ec0c53..ce12443da 100644 --- a/test/functional/pdo_sqlsrv/pdo_020_bind_params_array.phpt +++ b/test/functional/pdo_sqlsrv/pdo_020_bind_params_array.phpt @@ -12,6 +12,8 @@ try { // Create table $tableName = 'bindParams'; + dropTable($conn, $tableName); + $sql = "CREATE TABLE $tableName (ID TINYINT, SID CHAR(5))"; $stmt = $conn->exec($sql); diff --git a/test/functional/pdo_sqlsrv/pdo_040_error_information.phpt b/test/functional/pdo_sqlsrv/pdo_040_error_information.phpt index 93b6e2fd4..c8424856d 100644 --- a/test/functional/pdo_sqlsrv/pdo_040_error_information.phpt +++ b/test/functional/pdo_sqlsrv/pdo_040_error_information.phpt @@ -12,6 +12,8 @@ try { // Create table $tableName = 'pdo_040test'; + dropTable($conn, $tableName); + // common function insertRow() is not used here since the test deliberately // executes an invalid insertion statement // thus it's not necessary to create an encrypted column for testing column encryption diff --git a/test/functional/pdo_sqlsrv/pdo_065_construct_persistent.phpt b/test/functional/pdo_sqlsrv/pdo_065_construct_persistent.phpt index 883da0299..8f2d8e8f7 100644 --- a/test/functional/pdo_sqlsrv/pdo_065_construct_persistent.phpt +++ b/test/functional/pdo_sqlsrv/pdo_065_construct_persistent.phpt @@ -13,7 +13,7 @@ require_once("MsCommon_mid-refactor.inc"); try { echo "Testing a connection with ATTR_PERSISTENT...\n"; // setting PDO::ATTR_PERSISTENT in PDO constructor returns an exception - $dsn = getDSN($server, $databaseName); + $dsn = getDSN($server, $databaseName, $driver); $attr = array(PDO::ATTR_PERSISTENT => true); $conn = new PDO($dsn, $uid, $pwd, $attr); //free the connection diff --git a/test/functional/pdo_sqlsrv/pdo_065_construct_prefetch.phpt b/test/functional/pdo_sqlsrv/pdo_065_construct_prefetch.phpt index 463b7ac4d..88f47495f 100644 --- a/test/functional/pdo_sqlsrv/pdo_065_construct_prefetch.phpt +++ b/test/functional/pdo_sqlsrv/pdo_065_construct_prefetch.phpt @@ -10,7 +10,7 @@ require_once("MsSetup.inc"); require_once("MsCommon_mid-refactor.inc"); try { echo "Testing a connection with ATTR_PREFETCH before ERRMODE_EXCEPTION...\n"; - $dsn = getDSN($server, $databaseName); + $dsn = getDSN($server, $databaseName, $driver); $attr = array(PDO::ATTR_PREFETCH => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); $conn = new PDO($dsn, $uid, $pwd, $attr); diff --git a/test/functional/pdo_sqlsrv/pdo_ae_output_param_all.phpt b/test/functional/pdo_sqlsrv/pdo_ae_output_param_all.phpt index 580bbdcf3..ea20d7ec8 100644 --- a/test/functional/pdo_sqlsrv/pdo_ae_output_param_all.phpt +++ b/test/functional/pdo_sqlsrv/pdo_ae_output_param_all.phpt @@ -29,6 +29,7 @@ $colMetaArr = array("c1_int" => "int", createTable($conn, $tbname, $colMetaArr); // Create a Store Procedure $spname = 'selectAllColumns'; +dropProc($conn, $spname); $spSql = "CREATE PROCEDURE $spname ( @c1_int int OUTPUT, @c2_smallint smallint OUTPUT, @c3_tinyint tinyint OUTPUT, @c4_bit bit OUTPUT, diff --git a/test/functional/pdo_sqlsrv/pdo_utf8_conn.phpt b/test/functional/pdo_sqlsrv/pdo_utf8_conn.phpt index f51d3ba6b..a5c31e09e 100644 --- a/test/functional/pdo_sqlsrv/pdo_utf8_conn.phpt +++ b/test/functional/pdo_sqlsrv/pdo_utf8_conn.phpt @@ -4,6 +4,7 @@ UTF-8 connection strings --FILE-- ---FILE-- -query($query); - $master_key_row = $stmt->fetch(); - - $query = "SELECT name FROM sys.column_encryption_keys"; - $stmt = $conn->query($query); - $encryption_key_row = $stmt->fetch(); - - if ($master_key_row[0] == 'AEMasterKey' && $encryption_key_row[0] == 'AEColumnKey'){ - echo "Test Successfully done.\n"; - } - else { - die("Column Master Key and Column Encryption Key not created.\n"); - } - unset($stmt); -} -else { - echo "Test Successfully done.\n"; -} -unset($conn); -?> ---EXPECT-- +--TEST-- +Test the existence of Windows Always Encrypted keys generated in the database setup +--DESCRIPTION-- +This test iterates through the rows of sys.column_master_keys and/or +sys.column_encryption_keys to look for the specific column master key and +column encryption key generated in the database setup +--SKIPIF-- + +--FILE-- +query($query); + + // Do not assume the master key must be the first one created + $found = false; + while ($master_key_row = $stmt->fetch()) { + if ($master_key_row[0] == 'AEMasterKey') { + $found = true; + } + } + if (!$found) { + die("Windows Column Master Key not created.\n"); + } + + // Do not assume the encryption key must be the first one created + $query = "SELECT name FROM sys.column_encryption_keys"; + $stmt = $conn->query($query); + + $found = false; + while ($encryption_key_row = $stmt->fetch()) { + if ($encryption_key_row[0] == 'AEColumnKey') { + $found = true; + } + } + if (!$found) { + die("Windows Column Encryption Key not created.\n"); + } + unset($stmt); +} + +echo "Test Successfully done.\n"; +unset($conn); +?> +--EXPECT-- Test Successfully done. \ No newline at end of file diff --git a/test/functional/sqlsrv/MsSetup.inc b/test/functional/sqlsrv/MsSetup.inc index 1ec7ceef4..aec2b4bb1 100644 --- a/test/functional/sqlsrv/MsSetup.inc +++ b/test/functional/sqlsrv/MsSetup.inc @@ -18,7 +18,9 @@ $tableIndex = "php_test_table_index"; $procName = "php_test_proc"; $fileName = "php_test_file.dat"; -$connectionOptions = array("Database"=>$database, "UID"=>$userName, "PWD"=>$userPassword, "TraceOn"=>false); +$driver = "ODBC Driver 17 for SQL Server"; + +$connectionOptions = array("Database" => $database, "UID" => $userName, "PWD" => $userPassword, "TraceOn" => false, "Driver" => $driver); $daasMode = false; $marsMode = true; diff --git a/test/functional/sqlsrv/skipif_not_akv.inc b/test/functional/sqlsrv/skipif_not_akv.inc index f56a4522c..9746db712 100644 --- a/test/functional/sqlsrv/skipif_not_akv.inc +++ b/test/functional/sqlsrv/skipif_not_akv.inc @@ -4,6 +4,12 @@ if (! extension_loaded("sqlsrv")) { die("skip extension not loaded"); } +require_once("MsSetup.inc"); +if ($driver != "ODBC Driver 17 for SQL Server") { + // the testing is not set to use ODBC 17 + die("skip - AE feature not supported in the current environment."); +} + require_once('MsCommon.inc'); $conn = AE\connect(); diff --git a/test/functional/sqlsrv/test_ae_keys_setup.phpt b/test/functional/sqlsrv/test_ae_keys_setup.phpt index e70257a29..53a2c0fa6 100644 --- a/test/functional/sqlsrv/test_ae_keys_setup.phpt +++ b/test/functional/sqlsrv/test_ae_keys_setup.phpt @@ -1,5 +1,9 @@ --TEST-- -retrieval of names of column master key and column encryption key generated in the database setup +Test the existence of Windows Always Encrypted keys generated in the database setup +--DESCRIPTION-- +This test iterates through the rows of sys.column_master_keys and/or +sys.column_encryption_keys to look for the specific column master key and +column encryption key generated in the database setup --SKIPIF-- --FILE-- @@ -13,23 +17,34 @@ $conn = connect(); if (AE\IsQualified($conn)) { $query = "SELECT name FROM sys.column_master_keys"; $stmt = sqlsrv_query($conn, $query); - sqlsrv_fetch($stmt); - $master_key_name = sqlsrv_get_field($stmt, 0); + $found = false; + while (sqlsrv_fetch($stmt)) { + $master_key_name = sqlsrv_get_field($stmt, 0); + if ($master_key_name == 'AEMasterKey') { + $found = true; + } + } + // $master_key_name = sqlsrv_get_field($stmt, 0); + if (!$found) { + die("Windows Column Master Key not created.\n"); + } $query = "SELECT name FROM sys.column_encryption_keys"; $stmt = sqlsrv_query($conn, $query); - sqlsrv_fetch($stmt); - $encryption_key_name = sqlsrv_get_field($stmt, 0); - - if ($master_key_name == 'AEMasterKey' && $encryption_key_name == 'AEColumnKey') { - echo "Test Successfully done.\n"; - } else { - echo "Column Master Key and Column Encryption Key not created.\n"; + $found = false; + while (sqlsrv_fetch($stmt)) { + $encryption_key_name = sqlsrv_get_field($stmt, 0); + if ($encryption_key_name == 'AEColumnKey') { + $found = true; + } + } + if (!$found) { + die("Windows Column Encryption Key not created.\n"); } sqlsrv_free_stmt($stmt); -} else { - echo "Test Successfully done.\n"; } + +echo "Test Successfully done.\n"; sqlsrv_close($conn); ?> --EXPECT-- From 17fa64ac79c55ce1d52006a9dfc542d1b57f99f5 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Mon, 11 Jun 2018 11:36:22 -0700 Subject: [PATCH 05/32] Fixed connection pooling tests for more than one ODBC drivers --- test/functional/pdo_sqlsrv/PDO_ConnPool_Unix.phpt | 13 +++++++++++-- test/functional/sqlsrv/sqlsrv_ConnPool_Unix.phpt | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/test/functional/pdo_sqlsrv/PDO_ConnPool_Unix.phpt b/test/functional/pdo_sqlsrv/PDO_ConnPool_Unix.phpt index 05bf24a71..c68a46b14 100644 --- a/test/functional/pdo_sqlsrv/PDO_ConnPool_Unix.phpt +++ b/test/functional/pdo_sqlsrv/PDO_ConnPool_Unix.phpt @@ -6,6 +6,15 @@ This test assumes the default odbcinst.ini has not been modified. --FILE-- --FILE-- Date: Mon, 11 Jun 2018 12:10:33 -0700 Subject: [PATCH 06/32] added driver option to pdo isPooled.php --- test/functional/pdo_sqlsrv/isPooled.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/functional/pdo_sqlsrv/isPooled.php b/test/functional/pdo_sqlsrv/isPooled.php index b0be6e0ed..a25e3d1db 100644 --- a/test/functional/pdo_sqlsrv/isPooled.php +++ b/test/functional/pdo_sqlsrv/isPooled.php @@ -1,10 +1,10 @@ Date: Thu, 21 Jun 2018 14:29:09 -0700 Subject: [PATCH 07/32] Removed win32 ifdefs re connection resiliency (#802) --- source/pdo_sqlsrv/pdo_dbh.cpp | 6 ------ source/shared/core_sqlsrv.h | 4 ---- source/sqlsrv/conn.cpp | 6 ------ 3 files changed, 16 deletions(-) diff --git a/source/pdo_sqlsrv/pdo_dbh.cpp b/source/pdo_sqlsrv/pdo_dbh.cpp index 60d03eeb1..8154ac69f 100644 --- a/source/pdo_sqlsrv/pdo_dbh.cpp +++ b/source/pdo_sqlsrv/pdo_dbh.cpp @@ -43,10 +43,8 @@ const char AttachDBFileName[] = "AttachDbFileName"; const char Authentication[] = "Authentication"; const char ColumnEncryption[] = "ColumnEncryption"; const char ConnectionPooling[] = "ConnectionPooling"; -#ifdef _WIN32 const char ConnectRetryCount[] = "ConnectRetryCount"; const char ConnectRetryInterval[] = "ConnectRetryInterval"; -#endif // _WIN32 const char Database[] = "Database"; const char Driver[] = "Driver"; const char Encrypt[] = "Encrypt"; @@ -109,7 +107,6 @@ struct pdo_txn_isolation_conn_attr_func static void func( connection_option const* /*option*/, _In_ zval* value_z, _Inout_ sqlsrv_conn* conn, std::string& /*conn_str*/ TSRMLS_DC ); }; -#ifdef _WIN32 struct pdo_int_conn_str_func { static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) @@ -125,7 +122,6 @@ struct pdo_int_conn_str_func { conn_str += "};"; } }; -#endif // _WIN32 template struct pdo_int_conn_attr_func { @@ -243,7 +239,6 @@ const connection_option PDO_CONN_OPTS[] = { CONN_ATTR_STRING, column_encryption_set_func::func }, -#ifdef _WIN32 { PDOConnOptionNames::ConnectRetryCount, sizeof( PDOConnOptionNames::ConnectRetryCount ), @@ -262,7 +257,6 @@ const connection_option PDO_CONN_OPTS[] = { CONN_ATTR_INT, pdo_int_conn_str_func::func }, -#endif // _WIN32 { PDOConnOptionNames::Database, sizeof( PDOConnOptionNames::Database ), diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 39e53b19a..8ef19e97e 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -1112,10 +1112,8 @@ const char Driver[] = "Driver"; const char CharacterSet[] = "CharacterSet"; const char ConnectionPooling[] = "ConnectionPooling"; const char ColumnEncryption[] = "ColumnEncryption"; -#ifdef _WIN32 const char ConnectRetryCount[] = "ConnectRetryCount"; const char ConnectRetryInterval[] = "ConnectRetryInterval"; -#endif // _WIN32 const char Database[] = "Database"; const char Encrypt[] = "Encrypt"; const char Failover_Partner[] = "Failover_Partner"; @@ -1168,10 +1166,8 @@ enum SQLSRV_CONN_OPTIONS { SQLSRV_CONN_OPTION_KEYSTORE_PRINCIPAL_ID, SQLSRV_CONN_OPTION_KEYSTORE_SECRET, SQLSRV_CONN_OPTION_TRANSPARENT_NETWORK_IP_RESOLUTION, -#ifdef _WIN32 SQLSRV_CONN_OPTION_CONN_RETRY_COUNT, SQLSRV_CONN_OPTION_CONN_RETRY_INTERVAL, -#endif // _WIN32 // Driver specific connection options SQLSRV_CONN_OPTION_DRIVER_SPECIFIC = 1000, diff --git a/source/sqlsrv/conn.cpp b/source/sqlsrv/conn.cpp index 183ac3c55..c77a70de2 100644 --- a/source/sqlsrv/conn.cpp +++ b/source/sqlsrv/conn.cpp @@ -95,7 +95,6 @@ struct bool_conn_str_func { } }; -#ifdef _WIN32 struct int_conn_str_func { static void func( _In_ connection_option const* option, _In_ zval* value, sqlsrv_conn* /*conn*/, _Out_ std::string& conn_str TSRMLS_DC ) @@ -111,7 +110,6 @@ struct int_conn_str_func { conn_str += "};"; } }; -#endif // _WIN32 template struct int_conn_attr_func { @@ -188,10 +186,8 @@ const char Authentication[] = "Authentication"; const char CharacterSet[] = "CharacterSet"; const char ColumnEncryption[] = "ColumnEncryption"; const char ConnectionPooling[] = "ConnectionPooling"; -#ifdef _WIN32 const char ConnectRetryCount[] = "ConnectRetryCount"; const char ConnectRetryInterval[] = "ConnectRetryInterval"; -#endif // _WIN32 const char Database[] = "Database"; const char DateAsString[] = "ReturnDatesAsStrings"; const char Driver[] = "Driver"; @@ -324,7 +320,6 @@ const connection_option SS_CONN_OPTS[] = { CONN_ATTR_STRING, column_encryption_set_func::func }, -#ifdef _WIN32 { SSConnOptionNames::ConnectRetryCount, sizeof( SSConnOptionNames::ConnectRetryCount ), @@ -343,7 +338,6 @@ const connection_option SS_CONN_OPTS[] = { CONN_ATTR_INT, int_conn_str_func::func }, -#endif // _WIN32 { SSConnOptionNames::Database, sizeof( SSConnOptionNames::Database ), From eeea7878fb0a4724a1bc959ae0b46feb652ebe8c Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Tue, 26 Jun 2018 13:41:07 -0700 Subject: [PATCH 08/32] Set the driver argument for getDSN to null by default (#798) * Added the driver argument to getDSN * Dropped the driver argument but set to null as default * Removed the AE condition in locale support * Modified the AE condition for locale support --- test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc | 4 ++-- test/functional/sqlsrv/MsCommon.inc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc index 7aa915a0b..cf2ff605c 100644 --- a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc +++ b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc @@ -72,7 +72,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP * @param bool $disableCE : flag for disabling column encryption even when keystore is NOT none * @return string dsn string used for PDO constructor */ -function getDSN($sqlsrvserver, $database, $driver, $keywords = '', $disableCE = false) +function getDSN($sqlsrvserver, $database, $driver = null, $keywords = '', $disableCE = false) { require("MsSetup.inc"); $dsn = ""; @@ -85,7 +85,7 @@ function getDSN($sqlsrvserver, $database, $driver, $keywords = '', $disableCE = if ($database) { $dsn .= "database=$database;"; } - if ($driver) { + if (!is_null($driver)) { $dsn .= "driver=$driver;"; } if ($keystore != "none" && !$disableCE) { diff --git a/test/functional/sqlsrv/MsCommon.inc b/test/functional/sqlsrv/MsCommon.inc index 13900e2ec..def2d0f50 100644 --- a/test/functional/sqlsrv/MsCommon.inc +++ b/test/functional/sqlsrv/MsCommon.inc @@ -472,7 +472,7 @@ function isLocaleSupported() if (isWindows()) { return true; } - if (AE\isColEncrypted()) { + if (AE\isDataEncrypted()) { return false; } // now check ODBC version From ae0b95b757f231726a88332a0fd11da6daf09322 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Wed, 27 Jun 2018 11:03:30 -0700 Subject: [PATCH 09/32] Changed int to SQLLEN to avoid infinite loop (#806) --- source/shared/core_results.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/shared/core_results.cpp b/source/shared/core_results.cpp index 85a4ecdab..fc9935d5f 100644 --- a/source/shared/core_results.cpp +++ b/source/shared/core_results.cpp @@ -964,7 +964,7 @@ SQLRETURN binary_to_string( _Inout_ SQLCHAR* field_data, _Inout_ SQLLEN& read_so // to_copy contains the number of bytes to copy, so we divide the number in half (or quarter) // to get the number of hex digits we can copy SQLLEN to_copy_hex = to_copy / (2 * extra); - for( int i = 0; i < to_copy_hex; ++i ) { + for( SQLLEN i = 0; i < to_copy_hex; ++i ) { *h = hex_chars[ (*b & 0xf0) >> 4 ]; h++; *h = hex_chars[ (*b++ & 0x0f) ]; From 197489ab4fd171f87c7b6dbe82e632054413e262 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Wed, 27 Jun 2018 11:03:52 -0700 Subject: [PATCH 10/32] Version 5.3.0 (#803) * Version 5.3.0 * Fixed the wrong replacements * Added comments block to m4 files * Use dnl for comments --- LICENSE | 26 +++++++++++++------------- source/pdo_sqlsrv/config.m4 | 20 ++++++++++++++++++++ source/pdo_sqlsrv/config.w32 | 2 +- source/pdo_sqlsrv/pdo_dbh.cpp | 2 +- source/pdo_sqlsrv/pdo_init.cpp | 2 +- source/pdo_sqlsrv/pdo_parser.cpp | 2 +- source/pdo_sqlsrv/pdo_stmt.cpp | 2 +- source/pdo_sqlsrv/pdo_util.cpp | 2 +- source/pdo_sqlsrv/php_pdo_sqlsrv.h | 2 +- source/pdo_sqlsrv/template.rc | 2 +- source/shared/FormattedPrint.cpp | 2 +- source/shared/FormattedPrint.h | 2 +- source/shared/StringFunctions.cpp | 2 +- source/shared/StringFunctions.h | 2 +- source/shared/core_conn.cpp | 2 +- source/shared/core_init.cpp | 2 +- source/shared/core_results.cpp | 2 +- source/shared/core_sqlsrv.h | 2 +- source/shared/core_stmt.cpp | 2 +- source/shared/core_stream.cpp | 2 +- source/shared/core_util.cpp | 2 +- source/shared/globalization.h | 2 +- source/shared/interlockedatomic.h | 2 +- source/shared/interlockedatomic_gcc.h | 2 +- source/shared/interlockedslist.h | 2 +- source/shared/localization.hpp | 2 +- source/shared/localizationimpl.cpp | 2 +- source/shared/msodbcsql.h | 2 +- source/shared/sal_def.h | 2 +- source/shared/typedefs_for_linux.h | 2 +- source/shared/version.h | 8 ++++---- source/shared/xplat.h | 2 +- source/shared/xplat_intsafe.h | 2 +- source/shared/xplat_winerror.h | 2 +- source/shared/xplat_winnls.h | 2 +- source/sqlsrv/config.m4 | 20 ++++++++++++++++++++ source/sqlsrv/config.w32 | 2 +- source/sqlsrv/conn.cpp | 2 +- source/sqlsrv/init.cpp | 2 +- source/sqlsrv/php_sqlsrv.h | 2 +- source/sqlsrv/stmt.cpp | 2 +- source/sqlsrv/template.rc | 2 +- source/sqlsrv/util.cpp | 2 +- 43 files changed, 96 insertions(+), 56 deletions(-) diff --git a/LICENSE b/LICENSE index b52d9d433..13fab6115 100644 --- a/LICENSE +++ b/LICENSE @@ -1,14 +1,14 @@ -Copyright(c) 2017 Microsoft Corporation -All rights reserved. - -MIT License -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), -to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, -and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +Copyright(c) 2018 Microsoft Corporation +All rights reserved. + +MIT License +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/source/pdo_sqlsrv/config.m4 b/source/pdo_sqlsrv/config.m4 index 46e22960d..b1bfd6e48 100644 --- a/source/pdo_sqlsrv/config.m4 +++ b/source/pdo_sqlsrv/config.m4 @@ -1,3 +1,23 @@ +dnl ---------------------------------------------------------------------------------------------------------------------------------- +dnl File: config.m4 +dnl +dnl Contents: the code that will go into the configure script, indicating options, +dnl external libraries and includes, and what source files are to be compiled. +dnl +dnl Microsoft Drivers 5.3 for PHP for SQL Server +dnl Copyright(c) Microsoft Corporation +dnl All rights reserved. +dnl MIT License +dnl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""), +dnl to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +dnl and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : +dnl The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +dnl THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +dnl IN THE SOFTWARE. +dnl --------------------------------------------------------------------------------------------------------------------------------- + PHP_ARG_WITH(pdo_sqlsrv, for pdo_sqlsrv support, [ --with-pdo_sqlsrv Include pdo_sqlsrv support]) diff --git a/source/pdo_sqlsrv/config.w32 b/source/pdo_sqlsrv/config.w32 index bd1eaf048..7066e6254 100644 --- a/source/pdo_sqlsrv/config.w32 +++ b/source/pdo_sqlsrv/config.w32 @@ -3,7 +3,7 @@ // // Contents: JScript build configuration used by buildconf.bat // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/pdo_dbh.cpp b/source/pdo_sqlsrv/pdo_dbh.cpp index 8154ac69f..330205565 100644 --- a/source/pdo_sqlsrv/pdo_dbh.cpp +++ b/source/pdo_sqlsrv/pdo_dbh.cpp @@ -3,7 +3,7 @@ // // Contents: Implements the PDO object for PDO_SQLSRV // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/pdo_init.cpp b/source/pdo_sqlsrv/pdo_init.cpp index 0fa961c6e..65e7a0786 100644 --- a/source/pdo_sqlsrv/pdo_init.cpp +++ b/source/pdo_sqlsrv/pdo_init.cpp @@ -3,7 +3,7 @@ // // Contents: initialization routines for PDO_SQLSRV // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/pdo_parser.cpp b/source/pdo_sqlsrv/pdo_parser.cpp index 8c783b39f..baafeed73 100644 --- a/source/pdo_sqlsrv/pdo_parser.cpp +++ b/source/pdo_sqlsrv/pdo_parser.cpp @@ -5,7 +5,7 @@ // // Copyright Microsoft Corporation // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/pdo_stmt.cpp b/source/pdo_sqlsrv/pdo_stmt.cpp index fd65b9eac..d41dde3b7 100644 --- a/source/pdo_sqlsrv/pdo_stmt.cpp +++ b/source/pdo_sqlsrv/pdo_stmt.cpp @@ -3,7 +3,7 @@ // // Contents: Implements the PDOStatement object for the PDO_SQLSRV // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/pdo_util.cpp b/source/pdo_sqlsrv/pdo_util.cpp index 343537dd6..a05e75471 100644 --- a/source/pdo_sqlsrv/pdo_util.cpp +++ b/source/pdo_sqlsrv/pdo_util.cpp @@ -3,7 +3,7 @@ // // Contents: Utility functions used by both connection or statement functions // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/php_pdo_sqlsrv.h b/source/pdo_sqlsrv/php_pdo_sqlsrv.h index ba7dd4b76..38e4cec42 100644 --- a/source/pdo_sqlsrv/php_pdo_sqlsrv.h +++ b/source/pdo_sqlsrv/php_pdo_sqlsrv.h @@ -6,7 +6,7 @@ // // Contents: Declarations for the extension // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/pdo_sqlsrv/template.rc b/source/pdo_sqlsrv/template.rc index 248c99ccc..8b94ddfad 100644 --- a/source/pdo_sqlsrv/template.rc +++ b/source/pdo_sqlsrv/template.rc @@ -3,7 +3,7 @@ // // Contents: Version resource // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/FormattedPrint.cpp b/source/shared/FormattedPrint.cpp index 6a19a4259..1b48c0e92 100644 --- a/source/shared/FormattedPrint.cpp +++ b/source/shared/FormattedPrint.cpp @@ -6,7 +6,7 @@ // Contents: Contains functions for handling Windows format strings // and UTF-16 on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/FormattedPrint.h b/source/shared/FormattedPrint.h index 61080a424..87f15f463 100644 --- a/source/shared/FormattedPrint.h +++ b/source/shared/FormattedPrint.h @@ -4,7 +4,7 @@ // Contents: Contains functions for handling Windows format strings // and UTF-16 on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/StringFunctions.cpp b/source/shared/StringFunctions.cpp index 550c0d359..d5183fc52 100644 --- a/source/shared/StringFunctions.cpp +++ b/source/shared/StringFunctions.cpp @@ -3,7 +3,7 @@ // // Contents: Contains functions for handling UTF-16 on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/StringFunctions.h b/source/shared/StringFunctions.h index a0b31b783..b12e789b7 100644 --- a/source/shared/StringFunctions.h +++ b/source/shared/StringFunctions.h @@ -3,7 +3,7 @@ // // Contents: Contains functions for handling UTF-16 on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_conn.cpp b/source/shared/core_conn.cpp index 7f2d16eb5..b094e110b 100644 --- a/source/shared/core_conn.cpp +++ b/source/shared/core_conn.cpp @@ -3,7 +3,7 @@ // // Contents: Core routines that use connection handles shared between sqlsrv and pdo_sqlsrv // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_init.cpp b/source/shared/core_init.cpp index d47080066..cda38fa55 100644 --- a/source/shared/core_init.cpp +++ b/source/shared/core_init.cpp @@ -3,7 +3,7 @@ // // Contents: common initialization routines shared by PDO and sqlsrv // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_results.cpp b/source/shared/core_results.cpp index fc9935d5f..62a757d86 100644 --- a/source/shared/core_results.cpp +++ b/source/shared/core_results.cpp @@ -3,7 +3,7 @@ // // Contents: Result sets // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_sqlsrv.h b/source/shared/core_sqlsrv.h index 8ef19e97e..5530a5540 100644 --- a/source/shared/core_sqlsrv.h +++ b/source/shared/core_sqlsrv.h @@ -6,7 +6,7 @@ // // Contents: Core routines and constants shared by the Microsoft Drivers for PHP for SQL Server // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_stmt.cpp b/source/shared/core_stmt.cpp index 2cdb7a003..6d4d4f613 100644 --- a/source/shared/core_stmt.cpp +++ b/source/shared/core_stmt.cpp @@ -3,7 +3,7 @@ // // Contents: Core routines that use statement handles shared between sqlsrv and pdo_sqlsrv // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_stream.cpp b/source/shared/core_stream.cpp index 3167d1e83..32780a5b2 100644 --- a/source/shared/core_stream.cpp +++ b/source/shared/core_stream.cpp @@ -3,7 +3,7 @@ // // Contents: Implementation of PHP streams for reading SQL Server data // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/core_util.cpp b/source/shared/core_util.cpp index c537f766e..d8b7b2445 100644 --- a/source/shared/core_util.cpp +++ b/source/shared/core_util.cpp @@ -5,7 +5,7 @@ // // Comments: Mostly error handling and some type handling // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/globalization.h b/source/shared/globalization.h index 486a381d2..88e8d1a40 100644 --- a/source/shared/globalization.h +++ b/source/shared/globalization.h @@ -4,7 +4,7 @@ // Contents: Contains functions for handling Windows format strings // and UTF-16 on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/interlockedatomic.h b/source/shared/interlockedatomic.h index 39e615f48..cc0163f0f 100644 --- a/source/shared/interlockedatomic.h +++ b/source/shared/interlockedatomic.h @@ -4,7 +4,7 @@ // Contents: Contains a portable abstraction for interlocked, atomic // operations on int32_t and pointer types. // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/interlockedatomic_gcc.h b/source/shared/interlockedatomic_gcc.h index 7f5a974aa..e8c8e5bb2 100644 --- a/source/shared/interlockedatomic_gcc.h +++ b/source/shared/interlockedatomic_gcc.h @@ -4,7 +4,7 @@ // Contents: Contains a portable abstraction for interlocked, atomic // operations on int32_t and pointer types. // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/interlockedslist.h b/source/shared/interlockedslist.h index 6c88f0e59..bf2bc9ca2 100644 --- a/source/shared/interlockedslist.h +++ b/source/shared/interlockedslist.h @@ -4,7 +4,7 @@ // Contents: Contains a portable abstraction for interlocked, singly // linked list. // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/localization.hpp b/source/shared/localization.hpp index 136c5a519..2ec13e09d 100644 --- a/source/shared/localization.hpp +++ b/source/shared/localization.hpp @@ -3,7 +3,7 @@ // // Contents: Contains portable classes for localization // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/localizationimpl.cpp b/source/shared/localizationimpl.cpp index 92221e984..75251eb6d 100644 --- a/source/shared/localizationimpl.cpp +++ b/source/shared/localizationimpl.cpp @@ -5,7 +5,7 @@ // Must be included in one c/cpp file per binary // A build error will occur if this inclusion policy is not followed // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/msodbcsql.h b/source/shared/msodbcsql.h index d6b74a5b8..3a759252e 100644 --- a/source/shared/msodbcsql.h +++ b/source/shared/msodbcsql.h @@ -20,7 +20,7 @@ // pecuniary loss) arising out of the use of or inability to use // this SDK, even if Microsoft has been advised of the possibility // of such damages. -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/sal_def.h b/source/shared/sal_def.h index 7be9ba68a..78478eaa1 100644 --- a/source/shared/sal_def.h +++ b/source/shared/sal_def.h @@ -3,7 +3,7 @@ // // Contents: Contains the minimal definitions to build on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/typedefs_for_linux.h b/source/shared/typedefs_for_linux.h index 6daf7fcd6..dc3b4ca5b 100644 --- a/source/shared/typedefs_for_linux.h +++ b/source/shared/typedefs_for_linux.h @@ -1,7 +1,7 @@ //--------------------------------------------------------------------------------------------------------------------------------- // File: typedefs_for_linux.h // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/version.h b/source/shared/version.h index 140e24484..7d6554431 100644 --- a/source/shared/version.h +++ b/source/shared/version.h @@ -4,7 +4,7 @@ // File: version.h // Contents: Version number constants // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License @@ -26,12 +26,12 @@ // Increase Minor with backward compatible new functionalities and API changes. // Increase Patch for backward compatible fixes. #define SQLVERSION_MAJOR 5 -#define SQLVERSION_MINOR 2 -#define SQLVERSION_PATCH 1 +#define SQLVERSION_MINOR 3 +#define SQLVERSION_PATCH 0 #define SQLVERSION_BUILD 0 // For previews, set this constant to 1. Otherwise, set it to 0 -#define PREVIEW 1 +#define PREVIEW 0 #define SEMVER_PRERELEASE // Semantic versioning build metadata, build meta data is not counted in precedence order. diff --git a/source/shared/xplat.h b/source/shared/xplat.h index f768f112f..baa393e22 100644 --- a/source/shared/xplat.h +++ b/source/shared/xplat.h @@ -3,7 +3,7 @@ // // Contents: include for definition of Windows types for non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/xplat_intsafe.h b/source/shared/xplat_intsafe.h index 68595afb9..1baa473a7 100644 --- a/source/shared/xplat_intsafe.h +++ b/source/shared/xplat_intsafe.h @@ -4,7 +4,7 @@ // Contents: This module defines helper functions to prevent // integer overflow bugs. // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/xplat_winerror.h b/source/shared/xplat_winerror.h index 292960694..44eb7c844 100644 --- a/source/shared/xplat_winerror.h +++ b/source/shared/xplat_winerror.h @@ -3,7 +3,7 @@ // // Contents: Contains the minimal definitions to build on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/shared/xplat_winnls.h b/source/shared/xplat_winnls.h index 3b1cbc68b..36aceae16 100644 --- a/source/shared/xplat_winnls.h +++ b/source/shared/xplat_winnls.h @@ -3,7 +3,7 @@ // // Contents: Contains the minimal definitions to build on non-Windows platforms // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/config.m4 b/source/sqlsrv/config.m4 index e03ab0f4c..6b4190665 100644 --- a/source/sqlsrv/config.m4 +++ b/source/sqlsrv/config.m4 @@ -1,3 +1,23 @@ +dnl ---------------------------------------------------------------------------------------------------------------------------------- +dnl File: config.m4 +dnl +dnl Contents: the code that will go into the configure script, indicating options, +dnl external libraries and includes, and what source files are to be compiled. +dnl +dnl Microsoft Drivers 5.3 for PHP for SQL Server +dnl Copyright(c) Microsoft Corporation +dnl All rights reserved. +dnl MIT License +dnl Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files(the ""Software""), +dnl to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +dnl and / or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions : +dnl The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +dnl THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +dnl FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +dnl LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +dnl IN THE SOFTWARE. +dnl --------------------------------------------------------------------------------------------------------------------------------- + PHP_ARG_ENABLE(sqlsrv, whether to enable sqlsrv functions, [ --disable-sqlsrv Disable sqlsrv functions], yes) diff --git a/source/sqlsrv/config.w32 b/source/sqlsrv/config.w32 index 77d8c4d11..449789c4b 100644 --- a/source/sqlsrv/config.w32 +++ b/source/sqlsrv/config.w32 @@ -3,7 +3,7 @@ // // Contents: JScript build configuration used by buildconf.bat // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/conn.cpp b/source/sqlsrv/conn.cpp index c77a70de2..7bf805089 100644 --- a/source/sqlsrv/conn.cpp +++ b/source/sqlsrv/conn.cpp @@ -3,7 +3,7 @@ // // Contents: Routines that use connection handles // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/init.cpp b/source/sqlsrv/init.cpp index 7385dc6b1..bb8ab04b4 100644 --- a/source/sqlsrv/init.cpp +++ b/source/sqlsrv/init.cpp @@ -2,7 +2,7 @@ // File: init.cpp // Contents: initialization routines for the extension // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/php_sqlsrv.h b/source/sqlsrv/php_sqlsrv.h index 17175730a..6c5e7b015 100644 --- a/source/sqlsrv/php_sqlsrv.h +++ b/source/sqlsrv/php_sqlsrv.h @@ -8,7 +8,7 @@ // // Comments: Also contains "internal" declarations shared across source files. // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/stmt.cpp b/source/sqlsrv/stmt.cpp index 96aeae8a0..ac334cb9b 100644 --- a/source/sqlsrv/stmt.cpp +++ b/source/sqlsrv/stmt.cpp @@ -3,7 +3,7 @@ // // Contents: Routines that use statement handles // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/template.rc b/source/sqlsrv/template.rc index 446f50d88..ffee85372 100644 --- a/source/sqlsrv/template.rc +++ b/source/sqlsrv/template.rc @@ -3,7 +3,7 @@ // // Contents: Version resource // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License diff --git a/source/sqlsrv/util.cpp b/source/sqlsrv/util.cpp index 50b963e48..bc26658c0 100644 --- a/source/sqlsrv/util.cpp +++ b/source/sqlsrv/util.cpp @@ -5,7 +5,7 @@ // // Comments: Mostly error handling and some type handling // -// Microsoft Drivers 5.2 for PHP for SQL Server +// Microsoft Drivers 5.3 for PHP for SQL Server // Copyright(c) Microsoft Corporation // All rights reserved. // MIT License From aef3830479d7065bcd9391ebbe6856147921c036 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Wed, 27 Jun 2018 13:14:10 -0700 Subject: [PATCH 11/32] Modified AE fetch phptypes test to insert only one row at a time and loop through php types (#801) * Modified AE fetch phptypes test to insert only one row at a time and loop through php types * Fixed formatting --- .../sqlsrv/sqlsrv_ae_fetch_phptypes.phpt | 174 ++++++++++-------- 1 file changed, 93 insertions(+), 81 deletions(-) diff --git a/test/functional/sqlsrv/sqlsrv_ae_fetch_phptypes.phpt b/test/functional/sqlsrv/sqlsrv_ae_fetch_phptypes.phpt index 22c9f742f..59e184478 100644 --- a/test/functional/sqlsrv/sqlsrv_ae_fetch_phptypes.phpt +++ b/test/functional/sqlsrv/sqlsrv_ae_fetch_phptypes.phpt @@ -1,16 +1,17 @@ --TEST-- Test insert data and fetch as all possible php types +--DESCRIPTION-- +Test insert data of most common column types and fetch them all as possible php types --SKIPIF-- --FILE-- s; - - if ($diff == 0) { - $value = $valueAE; - } + + $dataArray = sqlsrv_fetch_array($stmt2, SQLSRV_FETCH_NUMERIC); + for ($i = 0; $i < sizeof($SQLSRV_PHPTYPE_CONST); ++$i) { + if (!sqlsrv_execute($stmt)) { + fatalError("Execute failed for $SQLSRV_PHPTYPE_CONST[$i]\n"); + } + + if ($result = sqlsrv_fetch($stmt)) { + for ($j = 0; $j < $numFields; $j++) { + $value = sqlsrv_get_field($stmt, $j, $SQLSRV_PHPTYPE_CONST[$i]); + $valueFromArray = $dataArray[$j]; + + // PHPTYPE_STREAM returns a PHP resource, so check the type + if (is_resource($value)) { + $value = get_resource_type($value); } - - if ($valueAE != $value or $valueFromArrayAE != $valueFromArray) { - echo "Values do not match! PHPType $i Field $j\n"; - print_r($valueAE);echo "\n"; - print_r($value);echo "\n"; - print_r($valueFromArrayAE);echo "\n"; - print_r($valueFromArray);echo "\n"; - print_r(sqlsrv_errors()); - fatalError("Test failed, values do not match.\n"); + + // For each type, the AE values come first and non-AE values second + // So let's do the comparison every second field + if ($j%2 == 0) { + $valueAE = $value; + $valueFromArrayAE = $valueFromArray; + } elseif ($j%2 == 1) { + // If returning a DateTime PHP type from a date only SQL type, + // PHP adds the current timestamp to make a DateTime object, + // and in this case the AE and non-AE times may be off by a + // fraction of a second since they are retrieved at ever-so-slightly + // different times. This not a test-failing discrepancy, so + // below the DateTime objects are made equal again for the next if + // block. + if ($value instanceof DateTime) { + // date_diff returns a DateInterval object, and s is + // the difference in seconds. s should be zero because + // the difference should be just a fraction of a second. + $datediff = date_diff($value, $valueAE); + $diff = $datediff->s; + + if ($diff == 0) { + $value = $valueAE; + } + } + + if ($valueAE != $value or $valueFromArrayAE != $valueFromArray) { + $index = floor($j / 2); + echo "Values do not match! PHPType $i Field $dataTypes[$index]\n"; + print_r($valueAE); + echo "\n--------\n\n"; + print_r($value); + echo "\n--------\n\n"; + print_r($valueFromArrayAE); + echo "\n--------\n\n"; + print_r($valueFromArray); + echo "\n--------\n\n"; + print_r(sqlsrv_errors()); + echo("Test failed, values do not match.\n"); + } } } } - ++$i; } - + sqlsrv_free_stmt($stmt); sqlsrv_free_stmt($stmt2); - - $deleteQuery = "DELETE FROM $tableName"; + + $deleteQuery = "TRUNCATE TABLE $tableName"; $stmt = sqlsrv_query($conn, $deleteQuery); if ($stmt == false) { print_r(sqlsrv_errors()); - fatalError("Delete statement failed"); + fatalError("Truncate statement failed"); } - + sqlsrv_free_stmt($stmt); } From 5aa9be7e13c10745e8f3ca6a680d30197cd03800 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Tue, 3 Jul 2018 16:47:14 -0700 Subject: [PATCH 12/32] Streamlined two very similar large column name tests (#807) * Streamlined two very similar large column name tests * Changed the EOL --- .../pdo_sqlsrv/PDO101_LargeColumnName.phpt | 95 ++++++++++--------- ...O101_LargeColumnName_unicode_col_name.phpt | 65 ++++++------- 2 files changed, 81 insertions(+), 79 deletions(-) diff --git a/test/functional/pdo_sqlsrv/PDO101_LargeColumnName.phpt b/test/functional/pdo_sqlsrv/PDO101_LargeColumnName.phpt index b5019290d..be6234f2e 100644 --- a/test/functional/pdo_sqlsrv/PDO101_LargeColumnName.phpt +++ b/test/functional/pdo_sqlsrv/PDO101_LargeColumnName.phpt @@ -1,76 +1,77 @@ ---TEST-- -PDO - Large Column Name Test ---DESCRIPTION-- -Verifies that long column names are supported (up to 128 chars). ---ENV-- -PHPT_EXEC=true ---SKIPIF-- - ---FILE-- +--TEST-- +PDO - Large Column Name Test +--DESCRIPTION-- +Verifies that long column names are supported (up to 128 chars). +--ENV-- +PHPT_EXEC=true +--SKIPIF-- + +--FILE-- query("CREATE TABLE [$tableName] ([$columnName] int)"); - $conn->query("INSERT INTO [$tableName] ([$columnName]) VALUES (5)"); $stmt = $conn->query("SELECT * from [$tableName]"); - if ( null == $stmt ) - { - if (!$expectfail) - FatalError("Possible regression: Unable to retrieve inserted value."); - } - - DropTable($conn, $tableName); - + dropTable($conn, $tableName); } //-------------------------------------------------------------------- -// Repro +// repro // //-------------------------------------------------------------------- -function Repro() +function repro() { - $testName = "PDO - Large Column Name Test"; - StartTest($testName); - - $columnName = "a"; - - try - { - for ($a = 1; $a <= 128; $a++) - { - LargeColumnNameTest($columnName, $a > 128); - $columnName .= "A"; - } - } - catch (Exception $e) - { - echo $e->getMessage(); + startTest($testName); + + // The maximum size of a column name is 128 characters + $maxlen = 128; + $columnName = str_repeat('A', $maxlen); + + try { + largeColumnNameTest($columnName); + } catch (Exception $e) { + echo "Possible regression: Unable to retrieve inserted value\n"; + print_r($e->getMessage()); + echo "\n"; } - - EndTest($testName); + + // Now add another character to the name + $columnName .= 'A'; + try { + largeColumnNameTest($columnName); + } catch (Exception $e) { + // Expects to fail + $expected = 'is too long. Maximum length is 128.'; + if (strpos($e->getMessage(), $expected) === false) { + print_r($e->getMessage()); + echo "\n"; + } + } + + endTest($testName); } -Repro(); -?> ---EXPECT-- -Test "PDO - Large Column Name Test" completed successfully. +repro(); +?> +--EXPECT-- +Test "PDO - Large Column Name Test" completed successfully. diff --git a/test/functional/pdo_sqlsrv/PDO101_LargeColumnName_unicode_col_name.phpt b/test/functional/pdo_sqlsrv/PDO101_LargeColumnName_unicode_col_name.phpt index 634dc5272..9ad27164e 100644 --- a/test/functional/pdo_sqlsrv/PDO101_LargeColumnName_unicode_col_name.phpt +++ b/test/functional/pdo_sqlsrv/PDO101_LargeColumnName_unicode_col_name.phpt @@ -8,69 +8,70 @@ PHPT_EXEC=true --FILE-- query("CREATE TABLE [$tableName] ([$columnName] int)"); - $conn->query("INSERT INTO [$tableName] ([$columnName]) VALUES (5)"); $stmt = $conn->query("SELECT * from [$tableName]"); - if ( null == $stmt ) - { - if (!$expectfail) - FatalError("Possible regression: Unable to retrieve inserted value."); - } - - DropTable($conn, $tableName); - + dropTable($conn, $tableName); } //-------------------------------------------------------------------- -// Repro +// repro // //-------------------------------------------------------------------- -function Repro() +function repro() { - $testName = "PDO - Large Column Name Test"; - StartTest($testName); + startTest($testName); - $columnName = "是"; + // The maximum size of a column name is 128 characters + $maxlen = 128; + $columnName = str_repeat('是', $maxlen); - try - { - for ($a = 1; $a <= 128; $a++) - { - LargeColumnNameTest($columnName, $a > 128); - $columnName .= "是"; - } + try { + largeColumnNameTest($columnName); + } catch (Exception $e) { + echo "Possible regression: Unable to retrieve inserted value\n"; + print_r($e->getMessage()); + echo "\n"; } - catch (Exception $e) - { - echo $e->getMessage(); + + // Now add another character to the name + $columnName .= '是'; + try { + largeColumnNameTest($columnName); + } catch (Exception $e) { + // Expects to fail + $expected = 'is too long. Maximum length is 128.'; + if (strpos($e->getMessage(), $expected) === false) { + print_r($e->getMessage()); + echo "\n"; + } } - EndTest($testName); + endTest($testName); } -Repro(); +repro(); + ?> --EXPECT-- Test "PDO - Large Column Name Test" completed successfully. From bbfe6df4cdf5f4e6b6340fa7d8d32aa3eb54ac55 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Thu, 5 Jul 2018 10:58:04 -0700 Subject: [PATCH 13/32] Updates to change log and readme (#811) * Updates to change log and readme * Dropped support for Ubuntu 17 * Modified as per review comments --- CHANGELOG.md | 35 +++++++++++++++++++++++++++++++++++ README.md | 20 +++++++------------- 2 files changed, 42 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 765bb786c..a3a6be270 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,41 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) +## 5.3.0 - 2018-07-20 +Updated PECL release packages. Here is the list of updates: + +### Added +- Added support for Azure Key Vault for Always Encrypted for basic CRUD functionalities such that Always Encrypted feature is available to all supported Windows, Linux or macOS platforms +- Added support for macOS High Sierra (requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) +- Added support for Ubuntu 18.04 LTS (requires MS ODBC Driver 17.2) +- Added support for Connection Resiliency to make it available to Linux or macOS users as well (requires MS ODBC Driver 17.2) + +### Fixed +- Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connection +- Issue [#678](https://github.com/Microsoft/msphpsql/issues/678) - Idle Connection Resiliency doesn't work with Connection Pooling bug +- Issue [#699](https://github.com/Microsoft/msphpsql/issues/699) - Binding output parameter failed when the query in the stored procedure returned no data. The test case has been added to the test lab. +- Issue [#705](https://github.com/Microsoft/msphpsql/issues/705) - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation +- Issue [#706](https://github.com/Microsoft/msphpsql/issues/706) - Always Encrypted - Cannot insert double with precision and scale (38, 38) +- Issue [#707](https://github.com/Microsoft/msphpsql/issues/707) - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers +- Issue [#735](https://github.com/Microsoft/msphpsql/issues/735) - Extended the buffer size for PDO lastInsertId such that data types other than integers can be supported +- Pull Request [#759](https://github.com/Microsoft/msphpsql/pull/759) - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY +- Pull Request [#775](https://github.com/Microsoft/msphpsql/pull/775) - Fixed the problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC + +### Limitations +- No support for inout / output params when using sql_variant type +- In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connection will not work +- Always Encrypted feature, which requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017) + - only Windows Certificate Store and Azure Key Vault are supported + - Issue [#716](https://github.com/Microsoft/msphpsql/issues/716) - With Always Encrypted feature enabled, Named Parameters in Sub Queries are not supported + - [Always Encrypted limitations](https://docs.microsoft.com/en-us/sql/connect/php/using-always-encrypted-php-drivers?view=sql-server-2017#limitations-of-the-php-drivers-when-using-always-encrypted) + +### Known Issues +- Connection pooling on Linux or macOS not recommended with [unixODBC](http://www.unixodbc.org/) < 2.3.6 +- When pooling is enabled in Linux or macOS + - unixODBC <= 2.3.4 (Linux and macOS) might not return proper diagnostics information, such as error messages, warnings and informative messages + - due to this unixODBC bug, fetch large data (such as xml, binary) as streams as a workaround. See the examples [here](https://github.com/Microsoft/msphpsql/wiki/Features#pooling) +- With ColumnEncryption enabled, calling stored procedures with XML parameters does not work (Issue [#674](https://github.com/Microsoft/msphpsql/issues/674)) + ## 5.2.1-preview - 2018-06-01 Updated PECL release packages. Here is the list of updates: diff --git a/README.md b/README.md index b30a3fa0f..a0172193b 100644 --- a/README.md +++ b/README.md @@ -47,7 +47,7 @@ For full details on the system requirements for the drivers, see the [system req On the client machine: - PHP 7.0.x, 7.1.x, or 7.2.x (7.2.0 and up on Unix, 7.2.1 and up on Windows) - A Web server such as Internet Information Services (IIS) is required. Your Web server must be configured to run PHP -- [Microsoft ODBC Driver 17][odbc17], [Microsoft ODBC Driver 13][odbc13], or [Microsoft ODBC Driver 11][odbc11] +- [Microsoft ODBC Driver 17, Microsoft ODBC Driver 13, or Microsoft ODBC Driver 11](https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-2017) On the server side, Microsoft SQL Server 2008 R2 and above on Windows are supported, as are Microsoft SQL Server 2016 and above on Linux. @@ -86,14 +86,14 @@ The version number may have trailing pre-release version identifiers to indicate - Build metadata may be denoted by a plus sign followed by 4 or 5 digits, such as `1.2.3-preview+5678` or `1.2.3+5678`. Build metadata does not figure into the precedence order. ## Future Plans -- Expand SQL Server 2016 feature support (example: Always Encrypted) +- Expand SQL Server 2016 feature support (example: Azure AD) - Add more verification/fundamental tests - Bug fixes ## Guidelines for Reporting Issues We appreciate you taking the time to test the driver, provide feedback and report any issues. It would be extremely helpful if you: -- First check the [FAQ](https://github.com/Microsoft/msphpsql/wiki/FAQ) +- First check the [FAQ](https://github.com/Microsoft/msphpsql/wiki/FAQ) for common problems - Report each issue as a new issue (but check first if it's already been reported) - Please address the questions in the new issue template and provide scripts, table schema, and/or any details that may help reproduce the problem(s) @@ -106,15 +106,15 @@ Thank you! **Q:** What's next? -**A:** On March 23, 2018 we released the production release version 5.2.0 of our PHP Driver. We will continue working on our future plans and releasing previews of upcoming releases frequently. +**A:** On July 20, 2018 we released the production release version 5.3.0 of our PHP Driver. We will continue working on our future plans and releasing previews of upcoming releases. **Q:** Is Microsoft taking pull requests for this project? -**A:** Yes. Please submit pull requests to the **dev** branch and not the **master** branch. +**A:** Yes. Please submit pull requests to the **dev** branch, not the **master** branch. ## License -The Microsoft Drivers for PHP for SQL Server are licensed under the MIT license. See the LICENSE file for more details. +The Microsoft Drivers for PHP for SQL Server are licensed under the MIT license. See the LICENSE file for more details. ## Code of conduct @@ -138,12 +138,6 @@ This project has adopted the Microsoft Open Source Code of Conduct. For more inf [phpbuild]: https://wiki.php.net/internals/windows/stepbystepbuild -[phpdoc]: http://msdn.microsoft.com/library/dd903047%28SQL.11%29.aspx - -[odbc11]: https://www.microsoft.com/download/details.aspx?id=36434 - -[odbc13]: https://www.microsoft.com/download/details.aspx?id=50420 - -[odbc17]: https://www.microsoft.com/download/details.aspx?id=56567 +[phpdoc]: https://docs.microsoft.com/en-us/sql/connect/php/microsoft-php-driver-for-sql-server?view=sql-server-2017 [PHPMan]: http://php.net/manual/install.unix.php From af9f77e1d19ec1b72ffe70400b1e75302704339d Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Tue, 10 Jul 2018 17:07:03 -0700 Subject: [PATCH 14/32] Fixed connection resiliency tests for Unix, updated AppVeyor for ODBC 17.2 --- appveyor.yml | 6 ++-- .../pdo_707_ae_output_param_decimals.phpt | 2 +- .../pdo_azure_ad_authentication.phpt | 1 + .../pdo_sqlsrv/pdo_connect_encrypted.phpt | 2 +- .../pdo_sqlsrv/pdo_connection_resiliency.phpt | 30 +++++++++---------- .../pdo_connection_resiliency_keywords.phpt | 13 ++++---- ...onnection_resiliency_prepare_transact.phpt | 12 ++++---- .../pdo_connection_resiliency_timeouts.phpt | 6 ++-- .../pdo_sqlsrv/skipif_protocol_not_tcp.inc | 2 -- .../skipif_version_less_than_2k14.inc | 2 -- .../skipif_version_less_than_2k16.inc | 2 -- .../sqlsrv/connection_resiliency.phpt | 12 ++++---- .../connection_resiliency_keywords.phpt | 15 +++++----- ...onnection_resiliency_prepare_transact.phpt | 12 ++++---- .../connection_resiliency_timeouts.phpt | 12 ++++---- .../sqlsrv/skipif_protocol_not_tcp.inc | 2 -- .../sqlsrv/skipif_version_less_than_2k14.inc | 2 -- .../sqlsrv/skipif_version_less_than_2k16.inc | 2 -- .../sqlsrv_azure_ad_authentication.phpt | 1 + 19 files changed, 62 insertions(+), 74 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 9d2cdeea1..4a0fcbddd 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -81,10 +81,10 @@ install: } Else { $env:PHP_VERSION=$env:PHP_MAJOR_VER + '.' + $env:PHP_MINOR_VER; } - - echo Downloading MSODBCSQL 17.1 + - echo Downloading MSODBCSQL 17.2 # AppVeyor build works are x64 VMs and 32-bit ODBC driver cannot be installed on it - - ps: (new-object net.webclient).DownloadFile('https://download.microsoft.com/download/E/6/B/E6BFDC7A-5BCD-4C51-9912-635646DA801E/msodbcsql_17.1.0.1_x64.msi', 'c:\projects\msodbcsql_17.1.0.1_x64.msi') - - cmd /c start /wait msiexec /i "c:\projects\msodbcsql_17.1.0.1_x64.msi" /q IACCEPTMSODBCSQLLICENSETERMS=YES ADDLOCAL=ALL + - ps: (new-object net.webclient).DownloadFile('https://download.microsoft.com/download/E/6/B/E6BFDC7A-5BCD-4C51-9912-635646DA801E/en-US/msodbcsql_17.2.0.1_x64.msi', 'c:\projects\msodbcsql_17.2.0.1_x64.msi') + - cmd /c start /wait msiexec /i "c:\projects\msodbcsql_17.2.0.1_x64.msi" /q IACCEPTMSODBCSQLLICENSETERMS=YES ADDLOCAL=ALL - echo Checking the version of MSODBCSQL - reg query "HKLM\SOFTWARE\ODBC\odbcinst.ini\ODBC Driver 17 for SQL Server" - dir %WINDIR%\System32\msodbcsql*.dll diff --git a/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt b/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt index 6b59c134e..8433d1940 100644 --- a/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt +++ b/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt @@ -7,7 +7,7 @@ do not need to be encrypted --ENV-- PHPT_EXEC=true --SKIPIF-- - + --FILE-- --FILE-- + --FILE-- --EXPECTREGEX-- -Statement 1 successful. -16 rows in result set. -Statement 2 successful. -9 rows in result set. -Statement 3 successful. --1 rows in result set. -Statement 4 successful. --1 rows in result set. -Statement 5 successful. --1 rows in result set. -Error executing statement 6. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. -Statement 7 successful. -Error executing statement 8. -SQLSTATE\[IMSSP\]: The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. +Statement 1 successful\. +16 rows in result set\. +Statement 2 successful\. +9 rows in result set\. +Statement 3 successful\. +-1 rows in result set\. +Statement 4 successful\. +-1 rows in result set\. +Statement 5 successful\. +-1 rows in result set\. +Error executing statement 6\. +SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x20) +Statement 7 successful\. +Error executing statement 8\. +SQLSTATE\[IMSSP\]: The connection cannot process this operation because there is a statement with pending results\. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_keywords.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_keywords.phpt index 1d7b066e9..b012eed98 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_keywords.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_keywords.phpt @@ -1,8 +1,7 @@ --TEST-- Test the connection resiliency keywords ConnectRetryCount and ConnectRetryInterval and their ranges of acceptable values --SKIPIF-- - + --FILE-- --EXPECTREGEX-- -Statement 1 prepared. -Statement 1 executed. -Transaction begun. -Transaction was committed. -Transaction begun. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. +Statement 1 prepared\. +Statement 1 executed\. +Transaction begun\. +Transaction was committed\. +Transaction begun\. +SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x20) SQLSTATE\[08S01\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt index 4389b3a95..375ae6372 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt @@ -83,6 +83,6 @@ DropTables( $server, $uid, $pwd, $tableName1, $tableName2 ); ?> --EXPECTREGEX-- -Error executing statement 1. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. -Query successfully executed. +Error executing statement 1\. +SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: [An existing connection was forcibly closed by the remote host\.|Error code 0x20] +Query successfully executed\. diff --git a/test/functional/pdo_sqlsrv/skipif_protocol_not_tcp.inc b/test/functional/pdo_sqlsrv/skipif_protocol_not_tcp.inc index 47a0d8d7d..e59d550b8 100644 --- a/test/functional/pdo_sqlsrv/skipif_protocol_not_tcp.inc +++ b/test/functional/pdo_sqlsrv/skipif_protocol_not_tcp.inc @@ -1,6 +1,4 @@ 08S01 \[SQLSTATE\] => 08S01 - \[1\] => 10054 - \[code\] => 10054 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. + \[1\] => (10054|104) + \[code\] => (10054|104) + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.Error code 0x68) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.Error code 0x68) \) @@ -229,8 +229,8 @@ Array \( \[0\] => 08S01 \[SQLSTATE\] => 08S01 - \[1\] => 10054 - \[code\] => 10054 + \[1\] => (10054|104) + \[code\] => (10054|104) \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure \) diff --git a/test/functional/sqlsrv/connection_resiliency_keywords.phpt b/test/functional/sqlsrv/connection_resiliency_keywords.phpt index 0211b47c1..7dd50fb57 100644 --- a/test/functional/sqlsrv/connection_resiliency_keywords.phpt +++ b/test/functional/sqlsrv/connection_resiliency_keywords.phpt @@ -3,8 +3,7 @@ Test the connection resiliency keywords --DESCRIPTION-- Test the connection resiliency keywords ConnectRetryCount and ConnectRetryInterval and their ranges of acceptable values --SKIPIF-- - + --FILE-- 08001 \[1\] => 0 \[code\] => 0 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' + \[2\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' + \[message\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' \) \) @@ -90,8 +89,8 @@ Array \[SQLSTATE\] => 08001 \[1\] => 0 \[code\] => 0 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval' - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval' + \[2\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval' + \[message\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryInterval' \) \) @@ -104,8 +103,8 @@ Array \[SQLSTATE\] => 08001 \[1\] => 0 \[code\] => 0 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' + \[2\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' + \[message\] => (\[unixODBC\]|)\[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Invalid value specified for connection string attribute 'ConnectRetryCount' \) \) diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index 3d713c2ee..49036d3b3 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -187,11 +187,11 @@ Array \( \[0\] => 08S02 \[SQLSTATE\] => 08S02 - \[1\] => 10054 - \[code\] => 10054 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. + \[1\] => (10054|-1) + \[code\] => (10054|-1) + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) \) @@ -199,8 +199,8 @@ Array \( \[0\] => 08S02 \[SQLSTATE\] => 08S02 - \[1\] => 10054 - \[code\] => 10054 + \[1\] => (10054|-1) + \[code\] => (10054|-1) \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session \) diff --git a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt index 06a8d28f3..c4d9ed13a 100644 --- a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt +++ b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt @@ -84,11 +84,11 @@ Array \( \[0\] => 08S01 \[SQLSTATE\] => 08S01 - \[1\] => 10054 - \[code\] => 10054 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. + \[1\] => (10054|104) + \[code\] => (10054|104) + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x68) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: An existing connection was forcibly closed by the remote host. + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x68) \) @@ -96,8 +96,8 @@ Array \( \[0\] => 08S01 \[SQLSTATE\] => 08S01 - \[1\] => 10054 - \[code\] => 10054 + \[1\] => (10054|104) + \[code\] => (10054|104) \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure \) diff --git a/test/functional/sqlsrv/skipif_protocol_not_tcp.inc b/test/functional/sqlsrv/skipif_protocol_not_tcp.inc index 4dc4921e7..26d960ca3 100644 --- a/test/functional/sqlsrv/skipif_protocol_not_tcp.inc +++ b/test/functional/sqlsrv/skipif_protocol_not_tcp.inc @@ -1,6 +1,4 @@ --FILE-- Date: Tue, 10 Jul 2018 19:44:48 -0700 Subject: [PATCH 15/32] Fixed expected output --- test/functional/sqlsrv/connection_resiliency.phpt | 6 ++---- .../sqlsrv/connection_resiliency_prepare_transact.phpt | 6 ++---- test/functional/sqlsrv/connection_resiliency_timeouts.phpt | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/test/functional/sqlsrv/connection_resiliency.phpt b/test/functional/sqlsrv/connection_resiliency.phpt index ebde2ea5a..ad88e923c 100644 --- a/test/functional/sqlsrv/connection_resiliency.phpt +++ b/test/functional/sqlsrv/connection_resiliency.phpt @@ -219,10 +219,8 @@ Array \[SQLSTATE\] => 08S01 \[1\] => (10054|104) \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.Error code 0x68) - - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.Error code 0x68) - + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) \) \[1\] => Array diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index 49036d3b3..8f5a3e1b9 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -189,10 +189,8 @@ Array \[SQLSTATE\] => 08S02 \[1\] => (10054|-1) \[code\] => (10054|-1) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) - - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) - + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) \) \[1\] => Array diff --git a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt index c4d9ed13a..b810d02e0 100644 --- a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt +++ b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt @@ -86,10 +86,8 @@ Array \[SQLSTATE\] => 08S01 \[1\] => (10054|104) \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x68) - - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x68) - + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) \) \[1\] => Array From 82be8141a3c56dc071acfc8a72669c76d9c35c26 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Wed, 11 Jul 2018 11:29:34 -0700 Subject: [PATCH 16/32] Fixed output and skipifs --- .../pdo_707_ae_output_param_decimals.phpt | 2 +- .../pdo_sqlsrv/pdo_connect_encrypted.phpt | 2 +- .../pdo_sqlsrv/pdo_connection_resiliency.phpt | 3 ++- .../pdo_connection_resiliency_keywords.phpt | 3 ++- ...onnection_resiliency_prepare_transact.phpt | 3 ++- .../pdo_connection_resiliency_timeouts.phpt | 3 ++- .../skipif_version_less_than_2k14.inc | 21 +++++++++++-------- ...onnection_resiliency_prepare_transact.phpt | 4 ++-- 8 files changed, 24 insertions(+), 17 deletions(-) diff --git a/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt b/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt index 8433d1940..67c0f4fd0 100644 --- a/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt +++ b/test/functional/pdo_sqlsrv/pdo_707_ae_output_param_decimals.phpt @@ -7,7 +7,7 @@ do not need to be encrypted --ENV-- PHPT_EXEC=true --SKIPIF-- - + --FILE-- + --FILE-- --FILE-- + --FILE-- --FILE-- --FILE-- query( "SELECT @@VERSION" ); -if ($stmt) { - $ver_string = $stmt->fetch(PDO::FETCH_NUM)[0]; -} else { - die( "skip Could not fetch SQL Server version during SKIPIF."); -} +// Exclude this check if running on Azure +if (!$daasMode) { + $stmt = $conn->query( "SELECT @@VERSION" ); + if ($stmt) { + $ver_string = $stmt->fetch(PDO::FETCH_NUM)[0]; + } else { + die( "skip Could not fetch SQL Server version during SKIPIF."); + } -$version = explode(' ', $ver_string); + $version = explode(' ', $ver_string); -if ($version[3] < '2014') { - die("skip Wrong version of SQL Server, 2014 or later required"); + if ($version[3] < '2014') { + die("skip Wrong version of SQL Server, 2014 or later required"); + } } ?> diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index 8f5a3e1b9..5d30280e2 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -189,8 +189,8 @@ Array \[SQLSTATE\] => 08S02 \[1\] => (10054|-1) \[code\] => (10054|-1) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]) + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\])\. + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\])\. \) \[1\] => Array From 0495513c07ce5cdadd0cbf79f7483fe5c76db9b6 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Wed, 11 Jul 2018 16:27:03 -0700 Subject: [PATCH 17/32] Fixed skipifs and output --- .../pdo_sqlsrv/MsCommon_mid-refactor.inc | 2 +- .../pdo_azure_ad_authentication.phpt | 1 - .../pdo_sqlsrv/pdo_connection_resiliency.phpt | 3 +- .../pdo_connection_resiliency_keywords.phpt | 3 +- ...onnection_resiliency_prepare_transact.phpt | 3 +- .../pdo_connection_resiliency_timeouts.phpt | 5 +-- .../skipif_version_less_than_2k14.inc | 16 ++++++++ .../skipif_version_less_than_2k16.inc | 21 ++++++----- ...onnection_resiliency_prepare_transact.phpt | 4 +- .../sqlsrv/skipif_version_less_than_2k14.inc | 37 ++++++++++++++----- .../sqlsrv/skipif_version_less_than_2k16.inc | 21 ++++++----- .../sqlsrv_azure_ad_authentication.phpt | 1 - 12 files changed, 76 insertions(+), 41 deletions(-) diff --git a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc index cf2ff605c..24633ff8f 100644 --- a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc +++ b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc @@ -48,7 +48,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP // simply use $databaseName from MsSetup.inc to facilitate testing in Azure, // which does not support switching databases require("MsSetup.inc"); - $dsn = getDSN($server, $databaseName, $driver, $keywords, $disableCE); + $dsn = getDSN($server, $databaseName, $DriverName, $keywords, $disableCE); $conn = new PDO($dsn, $uid, $pwd, $options); if ($errmode == PDO::ERRMODE_EXCEPTION || $errmode == PDO::ERRMODE_WARNING || $errmode == PDO::ERRMODE_SILENT) { $conn->setAttribute(PDO::ATTR_ERRMODE, $errmode); diff --git a/test/functional/pdo_sqlsrv/pdo_azure_ad_authentication.phpt b/test/functional/pdo_sqlsrv/pdo_azure_ad_authentication.phpt index 1e40da23b..0aea766f4 100644 --- a/test/functional/pdo_sqlsrv/pdo_azure_ad_authentication.phpt +++ b/test/functional/pdo_sqlsrv/pdo_azure_ad_authentication.phpt @@ -2,7 +2,6 @@ Test the Authentication keyword and three options: SqlPassword, ActiveDirectoryIntegrated, and ActiveDirectoryPassword. --SKIPIF-- --FILE-- --FILE-- + --FILE-- --FILE-- --FILE-- --EXPECTREGEX-- Error executing statement 1\. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: [An existing connection was forcibly closed by the remote host\.|Error code 0x20] +SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x20) Query successfully executed\. diff --git a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc index 52fc358a0..fefd0d347 100644 --- a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc +++ b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc @@ -1,8 +1,14 @@ getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"]; +$msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; +$msodbcsql_min = explode(".", $msodbcsql_ver)[1]; + +if (!$is_win) { + if ($msodbcsql_maj < 17 or $msodbcslq_min < 2) { + die("skip Unsupported ODBC driver version"); + } +} + // Get SQL Server Version // Exclude this check if running on Azure if (!$daasMode) { diff --git a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc index c384d07e0..5a413420c 100644 --- a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc +++ b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc @@ -11,16 +11,19 @@ if ($conn === false) { } // Get SQL Server Version -$stmt = $conn->query( "SELECT @@VERSION" ); -if ($stmt) { - $ver_string = $stmt->fetch(PDO::FETCH_NUM)[0]; -} else { - die( "skip Could not fetch SQL Server version during SKIPIF."); -} +// Exclude this check if running on Azure +if (!$daasMode) { + $stmt = $conn->query( "SELECT @@VERSION" ); + if ($stmt) { + $ver_string = $stmt->fetch(PDO::FETCH_NUM)[0]; + } else { + die( "skip Could not fetch SQL Server version during SKIPIF."); + } -$version = explode(' ', $ver_string); + $version = explode(' ', $ver_string); -if ($version[3] < '2016') { - die("skip Wrong version of SQL Server, 2016 or later required"); + if ($version[3] < '2016') { + die("skip Wrong version of SQL Server, 2016 or later required"); + } } ?> diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index 5d30280e2..98239aa89 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -189,8 +189,8 @@ Array \[SQLSTATE\] => 08S02 \[1\] => (10054|-1) \[code\] => (10054|-1) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\])\. - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\])\. + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]\. ) + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]\. ) \) \[1\] => Array diff --git a/test/functional/sqlsrv/skipif_version_less_than_2k14.inc b/test/functional/sqlsrv/skipif_version_less_than_2k14.inc index b57c7fae6..431ef3853 100644 --- a/test/functional/sqlsrv/skipif_version_less_than_2k14.inc +++ b/test/functional/sqlsrv/skipif_version_less_than_2k14.inc @@ -1,8 +1,14 @@ $userName, "PWD"=>$userPassword ); @@ -12,17 +18,30 @@ if ($conn === false) { die( "skip Could not connect during SKIPIF." ); } -// Get SQL Server version -$stmt = sqlsrv_query( $conn, "SELECT @@VERSION" ); -if (sqlsrv_fetch($stmt)) { - $ver_string = sqlsrv_get_field( $stmt, 0 ); -} else { - die("skip Could not fetch SQL Server version."); +$msodbcsql_ver = sqlsrv_client_info($conn)["DriverVer"]; +$msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; +$msodbcsql_min = explode(".", $msodbcsql_ver)[1]; + +if (!$is_win) { + if ($msodbcsql_maj < 17 or $msodbcslq_min < 2) { + die("skip Unsupported ODBC driver version"); + } } -$version = explode(' ', $ver_string); +// Get SQL Server version +// Exclude this check if running on Azure +if (!$daasMode) { + $stmt = sqlsrv_query( $conn, "SELECT @@VERSION" ); + if (sqlsrv_fetch($stmt)) { + $ver_string = sqlsrv_get_field( $stmt, 0 ); + } else { + die("skip Could not fetch SQL Server version."); + } + + $version = explode(' ', $ver_string); -if ($version[3] < '2014') { - die("skip Wrong version of SQL Server, 2014 or later required"); + if ($version[3] < '2014') { + die("skip Wrong version of SQL Server, 2014 or later required"); + } } ?> diff --git a/test/functional/sqlsrv/skipif_version_less_than_2k16.inc b/test/functional/sqlsrv/skipif_version_less_than_2k16.inc index 77b27f711..fdd4c11d5 100644 --- a/test/functional/sqlsrv/skipif_version_less_than_2k16.inc +++ b/test/functional/sqlsrv/skipif_version_less_than_2k16.inc @@ -13,16 +13,19 @@ if ($conn === false) { } // Get SQL Server version -$stmt = sqlsrv_query( $conn, "SELECT @@VERSION" ); -if (sqlsrv_fetch($stmt)) { - $ver_string = sqlsrv_get_field( $stmt, 0 ); -} else { - die("skip Could not fetch SQL Server version."); -} +// Exclude this check if running on Azure +if (!$daasMode) { + $stmt = sqlsrv_query( $conn, "SELECT @@VERSION" ); + if (sqlsrv_fetch($stmt)) { + $ver_string = sqlsrv_get_field( $stmt, 0 ); + } else { + die("skip Could not fetch SQL Server version."); + } -$version = explode(' ', $ver_string); + $version = explode(' ', $ver_string); -if ($version[3] < '2016') { - die("skip Wrong version of SQL Server, 2016 or later required"); + if ($version[3] < '2016') { + die("skip Wrong version of SQL Server, 2016 or later required"); + } } ?> diff --git a/test/functional/sqlsrv/sqlsrv_azure_ad_authentication.phpt b/test/functional/sqlsrv/sqlsrv_azure_ad_authentication.phpt index 85845adc4..bf9031123 100644 --- a/test/functional/sqlsrv/sqlsrv_azure_ad_authentication.phpt +++ b/test/functional/sqlsrv/sqlsrv_azure_ad_authentication.phpt @@ -2,7 +2,6 @@ Test the Authentication keyword and three options: SqlPassword, ActiveDirectoryIntegrated, and ActiveDirectoryPassword. --SKIPIF-- --FILE-- Date: Thu, 12 Jul 2018 13:24:04 -0700 Subject: [PATCH 18/32] Fixed driver name --- .../pdo_sqlsrv/MsCommon_mid-refactor.inc | 2 +- .../pdo_sqlsrv/skipif_version_less_than_2k16.inc | 16 ++++++++++++++++ .../sqlsrv/skipif_version_less_than_2k16.inc | 15 +++++++++++++++ 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc index 24633ff8f..cf2ff605c 100644 --- a/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc +++ b/test/functional/pdo_sqlsrv/MsCommon_mid-refactor.inc @@ -48,7 +48,7 @@ function connect($keywords = '', $options=array(), $errmode = PDO::ERRMODE_EXCEP // simply use $databaseName from MsSetup.inc to facilitate testing in Azure, // which does not support switching databases require("MsSetup.inc"); - $dsn = getDSN($server, $databaseName, $DriverName, $keywords, $disableCE); + $dsn = getDSN($server, $databaseName, $driver, $keywords, $disableCE); $conn = new PDO($dsn, $uid, $pwd, $options); if ($errmode == PDO::ERRMODE_EXCEPTION || $errmode == PDO::ERRMODE_WARNING || $errmode == PDO::ERRMODE_SILENT) { $conn->setAttribute(PDO::ATTR_ERRMODE, $errmode); diff --git a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc index 5a413420c..72553974b 100644 --- a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc +++ b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k16.inc @@ -1,8 +1,14 @@ getAttribute(PDO::ATTR_CLIENT_VERSION)["DriverVer"]; +$msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; +$msodbcsql_min = explode(".", $msodbcsql_ver)[1]; + +if (!$is_win) { + if ($msodbcsql_maj < 17) { + die("skip Unsupported ODBC driver version"); + } +} + // Get SQL Server Version // Exclude this check if running on Azure if (!$daasMode) { diff --git a/test/functional/sqlsrv/skipif_version_less_than_2k16.inc b/test/functional/sqlsrv/skipif_version_less_than_2k16.inc index fdd4c11d5..ce06258a2 100644 --- a/test/functional/sqlsrv/skipif_version_less_than_2k16.inc +++ b/test/functional/sqlsrv/skipif_version_less_than_2k16.inc @@ -1,8 +1,14 @@ $userName, "PWD"=>$userPassword ); @@ -12,6 +18,15 @@ if ($conn === false) { die( "skip Could not connect during SKIPIF." ); } +$msodbcsql_ver = sqlsrv_client_info($conn)["DriverVer"]; +$msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; + +if (!$is_win) { + if ($msodbcsql_maj < 17) { + die("skip Unsupported ODBC driver version"); + } +} + // Get SQL Server version // Exclude this check if running on Azure if (!$daasMode) { From 79be2821fa9b0fcdb7687b4852872021fd5a0ceb Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Thu, 12 Jul 2018 15:16:28 -0700 Subject: [PATCH 19/32] Updated installation instructions and sample script (#813) * Updated instructions and sample test for 5.3.0 RTW * Fixed sample code to adhere to php coding standard * Fixed cases and spaces * Modified NOTE for UB 18.04 based on review comments * Added 'exit' * Modified change log and readme based on review to PR 811 * Applied review comments --- CHANGELOG.md | 8 ++--- Linux-mac-install.md | 70 ++++++++++++++++++++++++-------------------- README.md | 2 +- 3 files changed, 43 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3a6be270..d4867eb95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,18 +10,18 @@ Updated PECL release packages. Here is the list of updates: - Added support for Azure Key Vault for Always Encrypted for basic CRUD functionalities such that Always Encrypted feature is available to all supported Windows, Linux or macOS platforms - Added support for macOS High Sierra (requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) - Added support for Ubuntu 18.04 LTS (requires MS ODBC Driver 17.2) -- Added support for Connection Resiliency to make it available to Linux or macOS users as well (requires MS ODBC Driver 17.2) +- Added support for Linux and macOS to Connection Resiliency (requires MS ODBC Driver 17.2) ### Fixed -- Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connection -- Issue [#678](https://github.com/Microsoft/msphpsql/issues/678) - Idle Connection Resiliency doesn't work with Connection Pooling bug +- Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connection (fixed in MS ODBC Driver 17.1) +- Issue [#678](https://github.com/Microsoft/msphpsql/issues/678) - Idle Connection Resiliency doesn't work with Connection Pooling bug (fixed in MS ODBC Driver 17.1) - Issue [#699](https://github.com/Microsoft/msphpsql/issues/699) - Binding output parameter failed when the query in the stored procedure returned no data. The test case has been added to the test lab. - Issue [#705](https://github.com/Microsoft/msphpsql/issues/705) - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation - Issue [#706](https://github.com/Microsoft/msphpsql/issues/706) - Always Encrypted - Cannot insert double with precision and scale (38, 38) - Issue [#707](https://github.com/Microsoft/msphpsql/issues/707) - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers - Issue [#735](https://github.com/Microsoft/msphpsql/issues/735) - Extended the buffer size for PDO lastInsertId such that data types other than integers can be supported - Pull Request [#759](https://github.com/Microsoft/msphpsql/pull/759) - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY -- Pull Request [#775](https://github.com/Microsoft/msphpsql/pull/775) - Fixed the problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC +- Pull Request [#775](https://github.com/Microsoft/msphpsql/pull/775) - Fixed the truncation problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC ### Limitations - No support for inout / output params when using sql_variant type diff --git a/Linux-mac-install.md b/Linux-mac-install.md index 6964ca0e2..d84eca655 100644 --- a/Linux-mac-install.md +++ b/Linux-mac-install.md @@ -1,20 +1,24 @@ -# PHP Linux and Mac Drivers Installation Tutorial -The following instructions assume a clean environment and show how to install PHP 7.x, the Microsoft ODBC driver, Apache, and the Microsoft drivers for PHP for Microsoft SQL Server on Ubuntu 16.04 and 17.10, RedHat 7, Debian 8 and 9, Suse 12, and macOS 10.11 and 10.12. These instructions advise installing the drivers using PECL, but you can also download the prebuilt binaries from the [Microsoft Drivers for PHP for Microsoft SQL Server](https://github.com/Microsoft/msphpsql/releases) Github project page and install them following the instructions in [Loading the Microsoft Drivers for PHP for Microsoft SQL Server](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver)). For an explanation of extension loading and why we do not add the extensions to php.ini, see the section on [loading the drivers](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver#loading-the-driver-at-php-startup). +# Linux and macOS Installation Tutorial for the Microsoft Drivers for PHP for SQL Server +The following instructions assume a clean environment and show how to install PHP 7.x, the Microsoft ODBC driver, Apache, and the Microsoft drivers for PHP for Microsoft SQL Server on Ubuntu 16.04, 17.10 and 18.04, RedHat 7, Debian 8 and 9, Suse 12, and macOS 10.11, 10.12 and 10.13. These instructions advise installing the drivers using PECL, but you can also download the prebuilt binaries from the [Microsoft Drivers for PHP for Microsoft SQL Server](https://github.com/Microsoft/msphpsql/releases) Github project page and install them following the instructions in [Loading the Microsoft Drivers for PHP for Microsoft SQL Server](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver)). For an explanation of extension loading and why we do not add the extensions to php.ini, see the section on [loading the drivers](https://docs.microsoft.com/sql/connect/php/loading-the-php-sql-driver#loading-the-driver-at-php-startup). -These instruction install PHP 7.2 by default -- see the notes at the beginning of each section to install PHP 7.0 or 7.1. +These instructions install PHP 7.2 by default -- see the notes at the beginning of each section to install PHP 7.0 or 7.1. ## Contents of this page: -- [Installing the drivers on Ubuntu 16.04 and 17.10](#installing-the-drivers-on-ubuntu-1604-and-1710) +- [Installing the drivers on Ubuntu 16.04, 17.10, and 18.04](#installing-the-drivers-on-ubuntu-1604-1710-and-1804) - [Installing the drivers on Red Hat 7](#installing-the-drivers-on-red-hat-7) - [Installing the drivers on Debian 8 and 9](#installing-the-drivers-on-debian-8-and-9) - [Installing the drivers on Suse 12](#installing-the-drivers-on-suse-12) - [Installing the drivers on macOS El Capitan, Sierra and High Sierra](#installing-the-drivers-on-macos-el-capitan-sierra-and-high-sierra) -## Installing the drivers on Ubuntu 16.04 and 17.10 +## Installing the drivers on Ubuntu 16.04, 17.10 and 18.04 > [!NOTE] > To install PHP 7.0 or 7.1, replace 7.2 with 7.0 or 7.1 in the following commands. +> For Ubuntu 18.04, the step to add the ondrej repository is not required unless +> PHP 7.0 or 7.1 is needed. However, installing PHP 7.0 or 7.1 in Ubuntu 18.04 may +> not work as packages from the ondrej repository come with dependencies that may +> conflict with a base Ubuntu 18.04 install. ### Step 1. Install PHP ``` @@ -44,6 +48,7 @@ a2enmod mpm_prefork a2enmod php7.2 echo "extension=pdo_sqlsrv.so" >> /etc/php/7.2/apache2/conf.d/30-pdo_sqlsrv.ini echo "extension=sqlsrv.so" >> /etc/php/7.2/apache2/conf.d/20-sqlsrv.ini +exit ``` ### Step 5. Restart Apache and test the sample script ``` @@ -86,11 +91,11 @@ echo extension=pdo_sqlsrv.so >> `php --ini | grep "Scan for additional .ini file echo extension=sqlsrv.so >> `php --ini | grep "Scan for additional .ini files" | sed -e "s|.*:\s*||"`/20-sqlsrv.ini exit ``` -An issue in PECL may prevent correct installation of the latest version of the drivers even if you have upgraded GCC. To install, download the packages and compile manually: +An issue in PECL may prevent correct installation of the latest version of the drivers even if you have upgraded GCC. To install, download the packages and compile manually (similar steps for pdo_sqlsrv): ``` pecl download sqlsrv -tar xvzf sqlsrv-5.2.0.tgz -cd sqlsrv-5.2.0/ +tar xvzf sqlsrv-5.3.0.tgz +cd sqlsrv-5.3.0/ phpize ./configure --with-php-config=/usr/bin/php-config make @@ -196,6 +201,7 @@ zypper install apache2 apache2-mod_php7 a2enmod php7 echo "extension=sqlsrv.so" >> /etc/php7/apache2/php.ini echo "extension=pdo_sqlsrv.so" >> /etc/php7/apache2/php.ini +exit ``` ### Step 5. Restart Apache and test the sample script ``` @@ -266,47 +272,47 @@ To test this sample script, create a file called testsql.php in your system's do "yourDatabase", - "Uid" => "yourUsername", - "PWD" => "yourPassword" + "database" => "yourDatabase", + "uid" => "yourUsername", + "pwd" => "yourPassword" ); -//Establishes the connection +// Establishes the connection $conn = sqlsrv_connect($serverName, $connectionOptions); -if( $conn === false ) { - die( FormatErrors( sqlsrv_errors())); +if ($conn === false) { + die(formatErrors(sqlsrv_errors())); } -//Select Query -$tsql= "SELECT @@Version as SQL_VERSION"; +// Select Query +$tsql = "SELECT @@Version AS SQL_VERSION"; -//Executes the query -$getResults= sqlsrv_query($conn, $tsql); +// Executes the query +$stmt = sqlsrv_query($conn, $tsql); -//Error handling -if ($getResults == FALSE) - die(FormatErrors(sqlsrv_errors())); +// Error handling +if ($stmt === false) { + die(formatErrors(sqlsrv_errors())); +} ?>

Results :

"); +while ($row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { + echo $row['SQL_VERSION'] . PHP_EOL; } -sqlsrv_free_stmt($getResults); +sqlsrv_free_stmt($stmt); +sqlsrv_close($conn); -function FormatErrors( $errors ) +function formatErrors($errors) { - /* Display errors. */ + // Display errors echo "Error information:
"; - foreach ( $errors as $error ) - { - echo "SQLSTATE: ".$error['SQLSTATE']."
"; - echo "Code: ".$error['code']."
"; - echo "Message: ".$error['message']."
"; + foreach ($errors as $error) { + echo "SQLSTATE: ". $error['SQLSTATE'] . "
"; + echo "Code: ". $error['code'] . "
"; + echo "Message: ". $error['message'] . "
"; } } ?> diff --git a/README.md b/README.md index a0172193b..20e3c0e98 100644 --- a/README.md +++ b/README.md @@ -86,7 +86,7 @@ The version number may have trailing pre-release version identifiers to indicate - Build metadata may be denoted by a plus sign followed by 4 or 5 digits, such as `1.2.3-preview+5678` or `1.2.3+5678`. Build metadata does not figure into the precedence order. ## Future Plans -- Expand SQL Server 2016 feature support (example: Azure AD) +- Expand SQL Server 2016 feature support (example: Azure Active Directory) - Add more verification/fundamental tests - Bug fixes From a18a59b5811288d3d25033feb2660021c42f4ffe Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 12 Jul 2018 16:28:41 -0700 Subject: [PATCH 20/32] build output to debug appveyor failure --- buildscripts/builddrivers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/buildscripts/builddrivers.py b/buildscripts/builddrivers.py index 4378ad1f1..3e62bf256 100644 --- a/buildscripts/builddrivers.py +++ b/buildscripts/builddrivers.py @@ -196,6 +196,7 @@ def build(self): print('Build Completed') except: print('Something went wrong, launching log file', logfile) + print(open(logfile, 'r').read()) # display log file only when not testing if not self.testing: os.startfile(os.path.join(root_dir, 'php-sdk', logfile)) From cb7897761b811c4f544c7f246c8c6af40cb581d5 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 12 Jul 2018 17:01:45 -0700 Subject: [PATCH 21/32] removed debug output --- buildscripts/builddrivers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/buildscripts/builddrivers.py b/buildscripts/builddrivers.py index 3e62bf256..4378ad1f1 100644 --- a/buildscripts/builddrivers.py +++ b/buildscripts/builddrivers.py @@ -196,7 +196,6 @@ def build(self): print('Build Completed') except: print('Something went wrong, launching log file', logfile) - print(open(logfile, 'r').read()) # display log file only when not testing if not self.testing: os.startfile(os.path.join(root_dir, 'php-sdk', logfile)) From 35631cffaebdb393648301793855813e712159b6 Mon Sep 17 00:00:00 2001 From: Jenny Tam Date: Fri, 13 Jul 2018 16:11:35 -0700 Subject: [PATCH 22/32] Streamlined two very similar large column name tests (#815) * Streamlined two very similar large column name tests * Added random number of test table names to avoid operand clash issues * Replaced to with for based on review --- CHANGELOG.md | 2 +- test/functional/sqlsrv/TC52_StreamSend.phpt | 2 +- .../sqlsrv/TC54_StreamPrepared.phpt | 2 +- .../sqlsrv/TC84_LargeColumnName.phpt | 49 ++++++------ .../sqlsrv/TC84_LargeColumnName_unicode.phpt | 51 +++++++------ ...TC84_LargeColumnName_unicode_col_name.phpt | 75 ------------------- 6 files changed, 60 insertions(+), 121 deletions(-) delete mode 100644 test/functional/sqlsrv/TC84_LargeColumnName_unicode_col_name.phpt diff --git a/CHANGELOG.md b/CHANGELOG.md index d4867eb95..0794d8dfe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ Updated PECL release packages. Here is the list of updates: - Added support for Azure Key Vault for Always Encrypted for basic CRUD functionalities such that Always Encrypted feature is available to all supported Windows, Linux or macOS platforms - Added support for macOS High Sierra (requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) - Added support for Ubuntu 18.04 LTS (requires MS ODBC Driver 17.2) -- Added support for Linux and macOS to Connection Resiliency (requires MS ODBC Driver 17.2) +- Added support for Linux and macOS for Connection Resiliency (requires MS ODBC Driver 17.2) ### Fixed - Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connection (fixed in MS ODBC Driver 17.1) diff --git a/test/functional/sqlsrv/TC52_StreamSend.phpt b/test/functional/sqlsrv/TC52_StreamSend.phpt index 648c23fdf..3779e4448 100644 --- a/test/functional/sqlsrv/TC52_StreamSend.phpt +++ b/test/functional/sqlsrv/TC52_StreamSend.phpt @@ -19,7 +19,7 @@ function sendStream($minType, $maxType, $atExec) startTest($testName); setup(); - $tableName = "TC52test"; + $tableName = "TC52test" . rand(0, 100); $fileName = "TC52test.dat"; $conn1 = AE\connect(); diff --git a/test/functional/sqlsrv/TC54_StreamPrepared.phpt b/test/functional/sqlsrv/TC54_StreamPrepared.phpt index 94a6bbe88..a22868f90 100644 --- a/test/functional/sqlsrv/TC54_StreamPrepared.phpt +++ b/test/functional/sqlsrv/TC54_StreamPrepared.phpt @@ -18,7 +18,7 @@ function sendStream($minType, $maxType) startTest($testName); setup(); - $tableName = "TC54test"; + $tableName = "TC54test" . rand(0, 100); $fileName = "TC53test.dat"; $conn1 = AE\connect(); diff --git a/test/functional/sqlsrv/TC84_LargeColumnName.phpt b/test/functional/sqlsrv/TC84_LargeColumnName.phpt index bebcfadc4..b7cc3d570 100644 --- a/test/functional/sqlsrv/TC84_LargeColumnName.phpt +++ b/test/functional/sqlsrv/TC84_LargeColumnName.phpt @@ -10,7 +10,7 @@ PHPT_EXEC=true 128); - $columnName .= "A"; - } - } catch (Exception $e) { - echo $e->getMessage(); - } + // The maximum size of a column name is 128 characters + $maxlen = 128; + $columnName = str_repeat('a', $maxlen); + largeColumnNameTest($columnName); + + // Now add another character to the name + $columnName .= "A"; + + largeColumnNameTest($columnName, true); endTest($testName); } diff --git a/test/functional/sqlsrv/TC84_LargeColumnName_unicode.phpt b/test/functional/sqlsrv/TC84_LargeColumnName_unicode.phpt index 48bdc11c9..7a0aca36f 100644 --- a/test/functional/sqlsrv/TC84_LargeColumnName_unicode.phpt +++ b/test/functional/sqlsrv/TC84_LargeColumnName_unicode.phpt @@ -10,35 +10,44 @@ PHPT_EXEC=true 'UTF-8' )); + $conn = connect(array('CharacterSet'=>'UTF-8')); $tableName = "LargeColumnNameTest"; dropTable($conn, $tableName); - sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)"); - - sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)"); + $stmt = sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)"); + if ($stmt == null) { + if (!$expectFail) { + fatalError("Possible regression: Unable to create test $tableName."); + } else { + $expected = 'is too long. Maximum length is 128.'; + if (strpos(sqlsrv_errors()[0]['message'], $expected) === false) { + print_r(sqlsrv_errors()); + } + echo "$"; + echo "stmt = null"; + echo "\n"; + } + } else { + sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)"); - $stmt = sqlsrv_query($conn, "SELECT * from [$tableName]"); + $stmt = sqlsrv_query($conn, "SELECT * from [$tableName]"); - if (null == $stmt) { - echo "$"; - echo "stmt = null"; - echo "\n"; - } else { if (null == sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { - if (!$expectfail) { + if (!$expectFail) { fatalError("Possible regression: Unable to retrieve inserted value."); } } sqlsrv_free_stmt($stmt); } + dropTable($conn, $tableName); + sqlsrv_close($conn); } @@ -53,16 +62,16 @@ function repro() startTest($testName); - $columnName = "银"; + // The maximum size of a column name is 128 characters + $maxlen = 128; + $columnName = str_repeat('银', $maxlen); - try { - for ($a = 1; $a <= 129; $a++) { - LargeColumnNameTest($columnName, $a > 128); - $columnName .= "银"; - } - } catch (Exception $e) { - echo $e->getMessage(); - } + largeColumnNameTest($columnName); + + // Now add another character to the name + $columnName .= "银"; + + largeColumnNameTest($columnName, true); endTest($testName); } diff --git a/test/functional/sqlsrv/TC84_LargeColumnName_unicode_col_name.phpt b/test/functional/sqlsrv/TC84_LargeColumnName_unicode_col_name.phpt deleted file mode 100644 index dc7a1eb2d..000000000 --- a/test/functional/sqlsrv/TC84_LargeColumnName_unicode_col_name.phpt +++ /dev/null @@ -1,75 +0,0 @@ ---TEST-- -PHP - Large Unicode Column Name Test ---DESCRIPTION-- -Verifies that long column names are supported (up to 128 chars). ---ENV-- -PHPT_EXEC=true ---SKIPIF-- - ---FILE-- -'UTF-8' )); - - $tableName = "LargeColumnNameTest"; - - dropTable($conn, $tableName); - - sqlsrv_query($conn, "CREATE TABLE [$tableName] ([$columnName] int)"); - - sqlsrv_query($conn, "INSERT INTO [$tableName] ([$columnName]) VALUES (5)"); - - $stmt = sqlsrv_query($conn, "SELECT * from [$tableName]"); - - if (null == $stmt) { - echo "$"; - echo "stmt = null"; - echo "\n"; - } else { - if (null == sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC)) { - if (!$expectfail) { - fatalError("Possible regression: Unable to retrieve inserted value."); - } - } - sqlsrv_free_stmt($stmt); - } - - sqlsrv_close($conn); -} - - -//-------------------------------------------------------------------- -// repro -// -//-------------------------------------------------------------------- -function repro() -{ - $testName = "PHP - Large Unicode Column Name Test"; - - startTest($testName); - - $columnName = "银"; - - try { - for ($a = 1; $a <= 129; $a++) { - LargeColumnNameTest($columnName, $a > 128); - $columnName .= "银"; - } - } catch (Exception $e) { - echo $e->getMessage(); - } - - - endTest($testName); -} - -repro(); -?> ---EXPECT-- -$stmt = null -Test "PHP - Large Unicode Column Name Test" completed successfully. From 706c526664b0fe47d0b14982d3a887af3fc85da2 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Wed, 18 Jul 2018 16:45:10 -0700 Subject: [PATCH 23/32] Changelog updated --- CHANGELOG.md | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0794d8dfe..86d31a036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,36 +7,36 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) Updated PECL release packages. Here is the list of updates: ### Added -- Added support for Azure Key Vault for Always Encrypted for basic CRUD functionalities such that Always Encrypted feature is available to all supported Windows, Linux or macOS platforms -- Added support for macOS High Sierra (requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) -- Added support for Ubuntu 18.04 LTS (requires MS ODBC Driver 17.2) -- Added support for Linux and macOS for Connection Resiliency (requires MS ODBC Driver 17.2) +- Added support for Azure Key Vault for Always Encrypted functionality. Always Encrypted functionality is supported on Linux and macOS through Azure Key Vault +- Added support for connection resiliency on Linux and macOS (requires version 17.2 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) +- Added support for macOS High Sierra (requires version 17 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) +- Added support for Ubuntu 18.04 (requires version 17.2 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) ### Fixed -- Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connection (fixed in MS ODBC Driver 17.1) -- Issue [#678](https://github.com/Microsoft/msphpsql/issues/678) - Idle Connection Resiliency doesn't work with Connection Pooling bug (fixed in MS ODBC Driver 17.1) -- Issue [#699](https://github.com/Microsoft/msphpsql/issues/699) - Binding output parameter failed when the query in the stored procedure returned no data. The test case has been added to the test lab. -- Issue [#705](https://github.com/Microsoft/msphpsql/issues/705) - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation -- Issue [#706](https://github.com/Microsoft/msphpsql/issues/706) - Always Encrypted - Cannot insert double with precision and scale (38, 38) -- Issue [#707](https://github.com/Microsoft/msphpsql/issues/707) - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers -- Issue [#735](https://github.com/Microsoft/msphpsql/issues/735) - Extended the buffer size for PDO lastInsertId such that data types other than integers can be supported -- Pull Request [#759](https://github.com/Microsoft/msphpsql/pull/759) - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY -- Pull Request [#775](https://github.com/Microsoft/msphpsql/pull/775) - Fixed the truncation problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC +- Issue #577 - Idle Connection Resiliency doesn't work with Column Encryption enabled connections (fixed in MS ODBC Driver 17.1) +- Issue #678 - Idle Connection Resiliency doesn't work with Connection Pooling (fixed in MS ODBC Driver 17.1) +- Issue #699 - Binding output parameters fails when the query in the stored procedure returns no data. The test case has been added to the test lab. +- Issue #705 - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation +- Issue #706 - Always Encrypted - Cannot insert double with precision and scale (38, 38) +- Issue #707 - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers +- Issue #735 - Extended the buffer size for PDO::lastInsertId so that data types other than integers can be supported +- Pull Request #759 - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY +- Pull Request #775 - Fixed the truncation problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC ### Limitations - No support for inout / output params when using sql_variant type -- In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connection will not work -- Always Encrypted feature, which requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017) - - only Windows Certificate Store and Azure Key Vault are supported - - Issue [#716](https://github.com/Microsoft/msphpsql/issues/716) - With Always Encrypted feature enabled, Named Parameters in Sub Queries are not supported +- In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connecting will not work +- Always Encrypted requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017) + - Only Windows Certificate Store and Azure Key Vault are supported. Custom Keystores are not supported + - Issue #716 - With Always Encrypted enabled, named parameters in subqueries are not supported - [Always Encrypted limitations](https://docs.microsoft.com/en-us/sql/connect/php/using-always-encrypted-php-drivers?view=sql-server-2017#limitations-of-the-php-drivers-when-using-always-encrypted) ### Known Issues -- Connection pooling on Linux or macOS not recommended with [unixODBC](http://www.unixodbc.org/) < 2.3.6 +- Connection pooling on Linux or macOS is not recommended with [unixODBC](http://www.unixodbc.org/) < 2.3.6 - When pooling is enabled in Linux or macOS - - unixODBC <= 2.3.4 (Linux and macOS) might not return proper diagnostics information, such as error messages, warnings and informative messages + - unixODBC <= 2.3.4 (Linux and macOS) might not return proper diagnostic information, such as error messages, warnings and informative messages - due to this unixODBC bug, fetch large data (such as xml, binary) as streams as a workaround. See the examples [here](https://github.com/Microsoft/msphpsql/wiki/Features#pooling) -- With ColumnEncryption enabled, calling stored procedures with XML parameters does not work (Issue [#674](https://github.com/Microsoft/msphpsql/issues/674)) +- With ColumnEncryption enabled, calling stored procedures with XML parameters does not work (Issue #674) ## 5.2.1-preview - 2018-06-01 Updated PECL release packages. Here is the list of updates: From 7b720e1f623eacfc8834c3de7cb2bace24ac7b6d Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Wed, 18 Jul 2018 17:01:54 -0700 Subject: [PATCH 24/32] changelog updated, test skipif changed to run on unix platforms --- CHANGELOG.md | 2 +- test/functional/sqlsrv/sqlsrv_connect_encrypted.phpt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 86d31a036..939a6e23d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,7 +27,7 @@ Updated PECL release packages. Here is the list of updates: - No support for inout / output params when using sql_variant type - In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connecting will not work - Always Encrypted requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017) - - Only Windows Certificate Store and Azure Key Vault are supported. Custom Keystores are not supported + - Only Windows Certificate Store and Azure Key Vault are supported. Custom Keystores are not yet supported - Issue #716 - With Always Encrypted enabled, named parameters in subqueries are not supported - [Always Encrypted limitations](https://docs.microsoft.com/en-us/sql/connect/php/using-always-encrypted-php-drivers?view=sql-server-2017#limitations-of-the-php-drivers-when-using-always-encrypted) diff --git a/test/functional/sqlsrv/sqlsrv_connect_encrypted.phpt b/test/functional/sqlsrv/sqlsrv_connect_encrypted.phpt index 5a39140e1..e6a5bbb6d 100644 --- a/test/functional/sqlsrv/sqlsrv_connect_encrypted.phpt +++ b/test/functional/sqlsrv/sqlsrv_connect_encrypted.phpt @@ -1,7 +1,7 @@ --TEST-- Test new connection keyword ColumnEncryption --SKIPIF-- - + --FILE-- Date: Wed, 18 Jul 2018 17:25:38 -0700 Subject: [PATCH 25/32] Fixed skipif typo --- test/functional/sqlsrv/skipif_version_less_than_2k14.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/sqlsrv/skipif_version_less_than_2k14.inc b/test/functional/sqlsrv/skipif_version_less_than_2k14.inc index 431ef3853..74d041fff 100644 --- a/test/functional/sqlsrv/skipif_version_less_than_2k14.inc +++ b/test/functional/sqlsrv/skipif_version_less_than_2k14.inc @@ -23,7 +23,7 @@ $msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; $msodbcsql_min = explode(".", $msodbcsql_ver)[1]; if (!$is_win) { - if ($msodbcsql_maj < 17 or $msodbcslq_min < 2) { + if ($msodbcsql_maj < 17 or $msodbcsql_min < 2) { die("skip Unsupported ODBC driver version"); } } From 6cd7dbc8b9de9899300da051ddd43918ab5e1011 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 10:59:32 -0700 Subject: [PATCH 26/32] Fixed typo in skipif for pdo --- test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc index fefd0d347..10849b9b2 100644 --- a/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc +++ b/test/functional/pdo_sqlsrv/skipif_version_less_than_2k14.inc @@ -21,7 +21,7 @@ $msodbcsql_maj = explode(".", $msodbcsql_ver)[0]; $msodbcsql_min = explode(".", $msodbcsql_ver)[1]; if (!$is_win) { - if ($msodbcsql_maj < 17 or $msodbcslq_min < 2) { + if ($msodbcsql_maj < 17 or $msodbcsql_min < 2) { die("skip Unsupported ODBC driver version"); } } From 820bc3199e91b9e48c014fd072da086cd8364df2 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 12:22:02 -0700 Subject: [PATCH 27/32] Fixed some output for Travis --- test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt | 3 +-- .../pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt | 3 +-- test/functional/sqlsrv/connection_resiliency.phpt | 4 ++-- test/functional/sqlsrv/connection_resiliency_timeouts.phpt | 4 ++-- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt index 3eb8b4f60..806f899d6 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt @@ -219,7 +219,6 @@ Statement 4 successful\. Statement 5 successful\. -1 rows in result set\. Error executing statement 6\. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x20) -Statement 7 successful\. +SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x20)Statement 7 successful\. Error executing statement 8\. SQLSTATE\[IMSSP\]: The connection cannot process this operation because there is a statement with pending results\. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt index b79705cd2..08424edaf 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt @@ -84,5 +84,4 @@ DropTables( $server, $uid, $pwd, $tableName1, $tableName2 ); ?> --EXPECTREGEX-- Error executing statement 1\. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x20) -Query successfully executed\. +SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x20 |SMux Provider: Physical connection is not usable \[xFFFFFFFF\]\. )Query successfully executed\. diff --git a/test/functional/sqlsrv/connection_resiliency.phpt b/test/functional/sqlsrv/connection_resiliency.phpt index ad88e923c..1f01f4826 100644 --- a/test/functional/sqlsrv/connection_resiliency.phpt +++ b/test/functional/sqlsrv/connection_resiliency.phpt @@ -219,8 +219,8 @@ Array \[SQLSTATE\] => 08S01 \[1\] => (10054|104) \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) \) \[1\] => Array diff --git a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt index b810d02e0..be370ad72 100644 --- a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt +++ b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt @@ -86,8 +86,8 @@ Array \[SQLSTATE\] => 08S01 \[1\] => (10054|104) \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68) + \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) + \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) \) \[1\] => Array From 0f66c4848bdad1e7e0fa2ed50b74851b892277ce Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 13:25:07 -0700 Subject: [PATCH 28/32] Moved error checking inside pdo connres tests --- .../pdo_sqlsrv/pdo_connection_resiliency.phpt | 41 +++++++++++-------- ...onnection_resiliency_prepare_transact.phpt | 28 ++++++++----- .../pdo_connection_resiliency_timeouts.phpt | 12 ++++-- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt index 806f899d6..5c9fe7b23 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency.phpt @@ -161,7 +161,11 @@ try { echo $rowcount." rows in result set.\n"; } catch (PDOException $e) { echo "Error executing statement 6.\n"; - print_r($e->getMessage()); + $err = $e->getMessage(); + if (strpos($err, 'SQLSTATE[08S02]')===false or (strpos($err, 'TCP Provider')===false and strpos($err, 'SMux Provider')===false)) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } unset($conn); @@ -200,25 +204,28 @@ try { } } catch (PDOException $e) { echo "Error executing statement 8.\n"; - print_r($e->getMessage()); + $err = $e->getMessage(); + if (strpos($err, 'SQLSTATE[IMSSP]')===false or strpos($err, 'The connection cannot process this operation because there is a statement with pending results')===false) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } unset($conn); unset($conn_break); ?> ---EXPECTREGEX-- -Statement 1 successful\. -16 rows in result set\. -Statement 2 successful\. -9 rows in result set\. -Statement 3 successful\. --1 rows in result set\. -Statement 4 successful\. --1 rows in result set\. -Statement 5 successful\. --1 rows in result set\. -Error executing statement 6\. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x20)Statement 7 successful\. -Error executing statement 8\. -SQLSTATE\[IMSSP\]: The connection cannot process this operation because there is a statement with pending results\. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. +--EXPECT-- +Statement 1 successful. +16 rows in result set. +Statement 2 successful. +9 rows in result set. +Statement 3 successful. +-1 rows in result set. +Statement 4 successful. +-1 rows in result set. +Statement 5 successful. +-1 rows in result set. +Error executing statement 6. +Statement 7 successful. +Error executing statement 8. diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_prepare_transact.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_prepare_transact.phpt index 95db2b5bd..5bd5a3482 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_prepare_transact.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_prepare_transact.phpt @@ -190,7 +190,12 @@ try } catch ( PDOException $e ) { - print_r( $e->getMessage() ); + echo "Transaction failed.\n"; + $err = $e->getMessage(); + if (strpos($err, 'SQLSTATE[08S02]')===false or (strpos($err, 'TCP Provider')===false and strpos($err, 'SMux Provider')===false)) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } // This try catch block prevents an Uncaught PDOException error that occurs @@ -201,17 +206,20 @@ try } catch ( PDOException $e ) { - print_r( $e->getMessage() ); + $err = $e->getMessage(); + if (strpos($err, 'SQLSTATE[08S01]')===false or strpos($err, 'Communication link failure')===false) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } $conn_break = null; ?> ---EXPECTREGEX-- -Statement 1 prepared\. -Statement 1 executed\. -Transaction begun\. -Transaction was committed\. -Transaction begun\. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.|Error code 0x20) -SQLSTATE\[08S01\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure +--EXPECT-- +Statement 1 prepared. +Statement 1 executed. +Transaction begun. +Transaction was committed. +Transaction begun. +Transaction failed. diff --git a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt index 08424edaf..279a7eb48 100644 --- a/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt +++ b/test/functional/pdo_sqlsrv/pdo_connection_resiliency_timeouts.phpt @@ -40,7 +40,11 @@ try catch( PDOException $e ) { echo "Error executing statement 1.\n"; - print_r( $e->getMessage() ); + $err = $e->getMessage(); + if (strpos($err, 'SQLSTATE[08S02]')===false or (strpos($err, 'TCP Provider')===false and strpos($err, 'SMux Provider')===false)) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } $conn = null; @@ -82,6 +86,6 @@ $conn_break = null; DropTables( $server, $uid, $pwd, $tableName1, $tableName2 ); ?> ---EXPECTREGEX-- -Error executing statement 1\. -SQLSTATE\[08S02\]: \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x20 |SMux Provider: Physical connection is not usable \[xFFFFFFFF\]\. )Query successfully executed\. +--EXPECT-- +Error executing statement 1. +Query successfully executed. From 495183e508793c1e81e69a822ea14910b1aadeea Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 14:02:06 -0700 Subject: [PATCH 29/32] Added links back to changelog --- CHANGELOG.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 939a6e23d..abaa24db6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,22 +13,22 @@ Updated PECL release packages. Here is the list of updates: - Added support for Ubuntu 18.04 (requires version 17.2 or higher of the [ODBC driver](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017)) ### Fixed -- Issue #577 - Idle Connection Resiliency doesn't work with Column Encryption enabled connections (fixed in MS ODBC Driver 17.1) -- Issue #678 - Idle Connection Resiliency doesn't work with Connection Pooling (fixed in MS ODBC Driver 17.1) -- Issue #699 - Binding output parameters fails when the query in the stored procedure returns no data. The test case has been added to the test lab. -- Issue #705 - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation -- Issue #706 - Always Encrypted - Cannot insert double with precision and scale (38, 38) -- Issue #707 - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers -- Issue #735 - Extended the buffer size for PDO::lastInsertId so that data types other than integers can be supported -- Pull Request #759 - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY -- Pull Request #775 - Fixed the truncation problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC +- Issue [#577](https://github.com/Microsoft/msphpsql/issues/577) - Idle Connection Resiliency doesn't work with Column Encryption enabled connections (fixed in MS ODBC Driver 17.1) +- Issue [#678](https://github.com/Microsoft/msphpsql/issues/678) - Idle Connection Resiliency doesn't work with Connection Pooling (fixed in MS ODBC Driver 17.1) +- Issue [#699](https://github.com/Microsoft/msphpsql/issues/699) - Binding output parameters fails when the query in the stored procedure returns no data. The test case has been added to the test lab. +- Issue [#705](https://github.com/Microsoft/msphpsql/issues/705) - Always Encrypted - Retrieving a negative decimal value (edge case) as output parameter causes truncation +- Issue [#706](https://github.com/Microsoft/msphpsql/issues/706) - Always Encrypted - Cannot insert double with precision and scale (38, 38) +- Issue [#707](https://github.com/Microsoft/msphpsql/issues/707) - Always Encrypted - Fetching decimals / numerics as output parameters bound to PDO::PARAM_BOOL or PDO::PARAM_INT returns floats, not integers +- Issue [#735](https://github.com/Microsoft/msphpsql/issues/735) - Extended the buffer size for PDO::lastInsertId so that data types other than integers can be supported +- Pull Request [#759](https://github.com/Microsoft/msphpsql/pull/759) - Removed the limitation of binding a binary as inout param as PDO::PARAM_STR with SQLSRV_ENCODING_BINARY +- Pull Request [#775](https://github.com/Microsoft/msphpsql/pull/775) - Fixed the truncation problem for output params with SQL types specified as SQLSRV_SQLTYPE_DECIMAL or SQLSRV_SQLTYPE_NUMERIC ### Limitations - No support for inout / output params when using sql_variant type - In Linux and macOS, setlocale() only takes effect if it is invoked before the first connection. Attempting to set the locale after connecting will not work - Always Encrypted requires [MS ODBC Driver 17+](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-2017) - Only Windows Certificate Store and Azure Key Vault are supported. Custom Keystores are not yet supported - - Issue #716 - With Always Encrypted enabled, named parameters in subqueries are not supported + - Issue [#716](https://github.com/Microsoft/msphpsql/issues/716) - With Always Encrypted enabled, named parameters in subqueries are not supported - [Always Encrypted limitations](https://docs.microsoft.com/en-us/sql/connect/php/using-always-encrypted-php-drivers?view=sql-server-2017#limitations-of-the-php-drivers-when-using-always-encrypted) ### Known Issues @@ -36,7 +36,7 @@ Updated PECL release packages. Here is the list of updates: - When pooling is enabled in Linux or macOS - unixODBC <= 2.3.4 (Linux and macOS) might not return proper diagnostic information, such as error messages, warnings and informative messages - due to this unixODBC bug, fetch large data (such as xml, binary) as streams as a workaround. See the examples [here](https://github.com/Microsoft/msphpsql/wiki/Features#pooling) -- With ColumnEncryption enabled, calling stored procedures with XML parameters does not work (Issue #674) +- With ColumnEncryption enabled, calling stored procedures with XML parameters does not work (Issue [#674](https://github.com/Microsoft/msphpsql/issues/674)) ## 5.2.1-preview - 2018-06-01 Updated PECL release packages. Here is the list of updates: From 96efbdb47b2d901df53b527f6e81468741514305 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 16:18:03 -0700 Subject: [PATCH 30/32] Fixed output for sqlsrv connres tests --- .../sqlsrv/connection_resiliency.phpt | 62 ++++--------------- ...onnection_resiliency_prepare_transact.phpt | 32 +++------- .../connection_resiliency_timeouts.phpt | 30 ++------- 3 files changed, 26 insertions(+), 98 deletions(-) diff --git a/test/functional/sqlsrv/connection_resiliency.phpt b/test/functional/sqlsrv/connection_resiliency.phpt index 1f01f4826..55a3daa24 100644 --- a/test/functional/sqlsrv/connection_resiliency.phpt +++ b/test/functional/sqlsrv/connection_resiliency.phpt @@ -144,7 +144,12 @@ $stmt6 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" ); if( $stmt6 === false ) { echo "Error in statement 6.\n"; - print_r( sqlsrv_errors() ); + $err = sqlsrv_errors(); + if (strpos($err[0][0], '08S01')===false or !($err[0][1]==10054 or $err[0][1]==104) or + (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false)) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } else { @@ -188,7 +193,12 @@ $stmt8 = sqlsrv_query( $conn, "SELECT * FROM $tableName2" ); if( $stmt8 === false ) { echo "Error in statement 8.\n"; - print_r( sqlsrv_errors() ); + $err = sqlsrv_errors(); + if (strpos($err[0][0], 'IMSSP')===false or $err[0][1]!=-44 or + strpos($err[0][2], 'The connection cannot process this operation because there is a statement with pending results')===false) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } else { @@ -199,7 +209,7 @@ sqlsrv_close( $conn ); sqlsrv_close( $conn_break ); ?> ---EXPECTREGEX-- +--EXPECT-- Statement 1 successful. 16 rows in result set. Statement 2 successful. @@ -211,51 +221,5 @@ Statement 4 successful. Statement 5 successful. rows in result set. Error in statement 6. -Array -\( - \[0\] => Array - \( - \[0\] => 08S01 - \[SQLSTATE\] => 08S01 - \[1\] => (10054|104) - \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) - \) - - \[1\] => Array - \( - \[0\] => 08S01 - \[SQLSTATE\] => 08S01 - \[1\] => (10054|104) - \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure - \) - -\) Statement 7 successful. Error in statement 8. -Array -\( - \[0\] => Array - \( - \[0\] => IMSSP - \[SQLSTATE\] => IMSSP - \[1\] => -44 - \[code\] => -44 - \[2\] => The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. - \[message\] => The connection cannot process this operation because there is a statement with pending results. To make the connection available for other queries, either fetch all results or cancel or free the statement. For more information, see the product documentation about the MultipleActiveResultSets connection option. - \) - - \[1\] => Array - \( - \[0\] => HY000 - \[SQLSTATE\] => HY000 - \[1\] => 0 - \[code\] => 0 - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Connection is busy with results for another command - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Connection is busy with results for another command - \) - -\) diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index 98239aa89..ae021b3d1 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -167,40 +167,22 @@ else else { echo "Statement not valid and rollback failed.\n"; - print_r( sqlsrv_errors() ); + $err = sqlsrv_errors(); + if (strpos($err[0][0], '08S02')===false or !($err[0][1]==10054 or $err[0][1]==-1) or + (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false)) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } } sqlsrv_close( $conn ); sqlsrv_close( $conn_break ); ?> ---EXPECTREGEX-- +--EXPECT-- Statement 1 prepared. Statement 1 executed. Transaction begun. Transaction was committed. Transaction begun. Statement not valid and rollback failed. -Array -\( - \[0\] => Array - \( - \[0\] => 08S02 - \[SQLSTATE\] => 08S02 - \[1\] => (10054|-1) - \[code\] => (10054|-1) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]\. ) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\](TCP Provider: An existing connection was forcibly closed by the remote host\.\n|SMux Provider: Physical connection is not usable \[xFFFFFFFF\]\. ) - \) - - \[1\] => Array - \( - \[0\] => 08S02 - \[SQLSTATE\] => 08S02 - \[1\] => (10054|-1) - \[code\] => (10054|-1) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Unable to open a logical session - \) - -\) diff --git a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt index be370ad72..8664be85d 100644 --- a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt +++ b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt @@ -33,7 +33,12 @@ $stmt1 = sqlsrv_query( $conn, "SELECT * FROM $tableName1" ); if( $stmt1 === false ) { echo "Error in statement 1.\n"; - print_r( sqlsrv_errors() ); + $err = sqlsrv_errors(); + if (strpos($err[0][0], '08S01')===false or !($err[0][1]==10054 or $err[0][1]==104) or + (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false)) { + echo "Error: Wrong error message.\n"; + print_r($err); + } } else { @@ -78,27 +83,4 @@ DropTables( $server, $uid, $pwd, $tableName1, $tableName2 ) ?> --EXPECTREGEX-- Error in statement 1. -Array -\( - \[0\] => Array - \( - \[0\] => 08S01 - \[SQLSTATE\] => 08S01 - \[1\] => (10054|104) - \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]TCP Provider: (An existing connection was forcibly closed by the remote host\.\n|Error code 0x68|Error code 0x2746) - \) - - \[1\] => Array - \( - \[0\] => 08S01 - \[SQLSTATE\] => 08S01 - \[1\] => (10054|104) - \[code\] => (10054|104) - \[2\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure - \[message\] => \[Microsoft\]\[ODBC Driver 1[1-9] for SQL Server\]Communication link failure - \) - -\) Statement 2 successful. From 825b429a1174f3c24594230ca4888ac9d289ac54 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 16:43:33 -0700 Subject: [PATCH 31/32] Fixed output --- test/functional/sqlsrv/connection_resiliency.phpt | 4 ++-- .../sqlsrv/connection_resiliency_prepare_transact.phpt | 2 +- test/functional/sqlsrv/connection_resiliency_timeouts.phpt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/functional/sqlsrv/connection_resiliency.phpt b/test/functional/sqlsrv/connection_resiliency.phpt index 55a3daa24..f7c4bf553 100644 --- a/test/functional/sqlsrv/connection_resiliency.phpt +++ b/test/functional/sqlsrv/connection_resiliency.phpt @@ -145,8 +145,8 @@ if( $stmt6 === false ) { echo "Error in statement 6.\n"; $err = sqlsrv_errors(); - if (strpos($err[0][0], '08S01')===false or !($err[0][1]==10054 or $err[0][1]==104) or - (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false)) { + if (strpos($err[0][0], '08S01')===false or + (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) { echo "Error: Wrong error message.\n"; print_r($err); } diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index ae021b3d1..274a24af0 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -169,7 +169,7 @@ else echo "Statement not valid and rollback failed.\n"; $err = sqlsrv_errors(); if (strpos($err[0][0], '08S02')===false or !($err[0][1]==10054 or $err[0][1]==-1) or - (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false)) { + (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) { echo "Error: Wrong error message.\n"; print_r($err); } diff --git a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt index 8664be85d..9685f4ac2 100644 --- a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt +++ b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt @@ -35,7 +35,7 @@ if( $stmt1 === false ) echo "Error in statement 1.\n"; $err = sqlsrv_errors(); if (strpos($err[0][0], '08S01')===false or !($err[0][1]==10054 or $err[0][1]==104) or - (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false)) { + (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) { echo "Error: Wrong error message.\n"; print_r($err); } From 6ee8c44e932353bf78bae23aaf5a9f586225d461 Mon Sep 17 00:00:00 2001 From: David Puglielli Date: Thu, 19 Jul 2018 16:45:15 -0700 Subject: [PATCH 32/32] Fixed output again --- test/functional/sqlsrv/connection_resiliency.phpt | 2 +- .../sqlsrv/connection_resiliency_prepare_transact.phpt | 2 +- test/functional/sqlsrv/connection_resiliency_timeouts.phpt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/functional/sqlsrv/connection_resiliency.phpt b/test/functional/sqlsrv/connection_resiliency.phpt index f7c4bf553..2d47f6fe5 100644 --- a/test/functional/sqlsrv/connection_resiliency.phpt +++ b/test/functional/sqlsrv/connection_resiliency.phpt @@ -194,7 +194,7 @@ if( $stmt8 === false ) { echo "Error in statement 8.\n"; $err = sqlsrv_errors(); - if (strpos($err[0][0], 'IMSSP')===false or $err[0][1]!=-44 or + if (strpos($err[0][0], 'IMSSP')===false or strpos($err[0][2], 'The connection cannot process this operation because there is a statement with pending results')===false) { echo "Error: Wrong error message.\n"; print_r($err); diff --git a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt index 274a24af0..c42a4e447 100644 --- a/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt +++ b/test/functional/sqlsrv/connection_resiliency_prepare_transact.phpt @@ -168,7 +168,7 @@ else { echo "Statement not valid and rollback failed.\n"; $err = sqlsrv_errors(); - if (strpos($err[0][0], '08S02')===false or !($err[0][1]==10054 or $err[0][1]==-1) or + if (strpos($err[0][0], '08S02')===false or (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) { echo "Error: Wrong error message.\n"; print_r($err); diff --git a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt index 9685f4ac2..1abfdd309 100644 --- a/test/functional/sqlsrv/connection_resiliency_timeouts.phpt +++ b/test/functional/sqlsrv/connection_resiliency_timeouts.phpt @@ -34,7 +34,7 @@ if( $stmt1 === false ) { echo "Error in statement 1.\n"; $err = sqlsrv_errors(); - if (strpos($err[0][0], '08S01')===false or !($err[0][1]==10054 or $err[0][1]==104) or + if (strpos($err[0][0], '08S01')===false or (strpos($err[0][2], 'TCP Provider:')===false and strpos($err[0][2], 'SMux Provider:')===false and strpos($err[0][2], 'Session Provider:')===false)) { echo "Error: Wrong error message.\n"; print_r($err);