Further reverted changes to distinguish datetime fields (#1178)
This commit is contained in:
parent
f02aefd6bd
commit
6349d06fee
|
@ -746,32 +746,23 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
|
|||
ind_ptr = SQL_NULL_DATA;
|
||||
}
|
||||
|
||||
core::SQLBindParameter( stmt, param_num + 1, direction,
|
||||
c_type, sql_type, column_size, decimal_digits, buffer, buffer_len, &ind_ptr );
|
||||
|
||||
|
||||
// When calling SQLDescribeParam() on a parameter targeting a Datetime column, the return values for ParameterType, ColumnSize and DecimalDigits are SQL_TYPE_TIMESTAMP, 23, and 3 respectively.
|
||||
// For a parameter targeting a SmallDatetime column, the return values are SQL_TYPE_TIMESTAMP, 16, and 0. Inputting these values into SQLBindParameter() results in Operand type clash error.
|
||||
// This is because SQL_TYPE_TIMESTAMP corresponds to Datetime2 by default, and conversion of Datetime2 to Datetime and conversion of Datetime2 to SmallDatatime is not allowed with encrypted columns.
|
||||
// To fix the conversion problem, set the SQL_CA_SS_SERVER_TYPE field of the parameter to SQL_SS_TYPE_DATETIME and SQL_SS_TYPE_SMALLDATETIME respectively for a Datetime and Smalldatetime column.
|
||||
// Note this must be called after SQLBindParameter() or SQLSetDescField() may fail.
|
||||
// TODO: how to correctly distinguish datetime from datetime2(3)? Both have the same decimal_digits and column_size
|
||||
if (stmt->conn->ce_option.enabled && sql_type == SQL_TYPE_TIMESTAMP) {
|
||||
if (decimal_digits == 0 || decimal_digits == 3) {
|
||||
SQLHDESC hIpd = NULL;
|
||||
SQLRETURN r = SQL_SUCCESS;
|
||||
|
||||
core::SQLGetStmtAttr(stmt, SQL_ATTR_IMP_PARAM_DESC, &hIpd, 0, 0);
|
||||
if (hIpd != NULL) {
|
||||
if (decimal_digits == 0 && column_size == 16) {
|
||||
r = ::SQLSetDescField(hIpd, param_num + 1, SQL_CA_SS_SERVER_TYPE, (SQLPOINTER)SQL_SS_TYPE_SMALLDATETIME, SQL_IS_INTEGER);
|
||||
} else if (decimal_digits == 3) {
|
||||
r = ::SQLSetDescField(hIpd, param_num + 1, SQL_CA_SS_SERVER_TYPE, (SQLPOINTER)SQL_SS_TYPE_DATETIME, SQL_IS_INTEGER);
|
||||
}
|
||||
CHECK_SQL_ERROR_OR_WARNING(r, stmt) {
|
||||
throw core::CoreException();
|
||||
}
|
||||
}
|
||||
if (decimal_digits == 3) {
|
||||
core::SQLSetDescField(stmt, param_num + 1, SQL_CA_SS_SERVER_TYPE, (SQLPOINTER)SQL_SS_TYPE_DATETIME, SQL_IS_INTEGER);
|
||||
} else if (decimal_digits == 0 && column_size == 16) {
|
||||
core::SQLSetDescField(stmt, param_num + 1, SQL_CA_SS_SERVER_TYPE, (SQLPOINTER)SQL_SS_TYPE_SMALLDATETIME, SQL_IS_INTEGER);
|
||||
}
|
||||
}
|
||||
|
||||
core::SQLBindParameter( stmt, param_num + 1, direction,
|
||||
c_type, sql_type, column_size, decimal_digits, buffer, buffer_len, &ind_ptr );
|
||||
|
||||
}
|
||||
catch( core::CoreException& e ){
|
||||
stmt->free_param_data();
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
--TEST--
|
||||
Test for inserting and retrieving encrypted data of datetime and smalldatetime types encrypted
|
||||
--DESCRIPTION--
|
||||
Verify that inserting into smalldatetime column might trigger "Datetime field overflow" error
|
||||
Verify that inserting into smalldatetime column (if encrypted) might trigger "Datetime field overflow" error
|
||||
--SKIPIF--
|
||||
<?php require('skipif_mid-refactor.inc'); ?>
|
||||
--FILE--
|
||||
|
@ -45,7 +45,7 @@ function createTablePlainQuery($conn, $tableName, $columns)
|
|||
try {
|
||||
// This test requires to connect with the Always Encrypted feature
|
||||
// First check if the system is qualified to run this test
|
||||
$dsn = getDSN($server, null);
|
||||
$dsn = "sqlsrv:Server=$server; Database=$databaseName;";
|
||||
$conn = new PDO($dsn, $uid, $pwd);
|
||||
$qualified = isAEQualified($conn) && (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN');
|
||||
|
||||
|
@ -89,9 +89,9 @@ try {
|
|||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
$error = ($qualified || isColEncrypted())? '*Datetime field overflow' : '*The conversion of a nvarchar data type to a smalldatetime data type resulted in an out-of-range value.';
|
||||
$error = ($qualified)? '*Datetime field overflow' : '*The conversion of a nvarchar data type to a smalldatetime data type resulted in an out-of-range value.';
|
||||
if (!fnmatch($error, $e->getMessage())) {
|
||||
echo "The error message is unexpected:\n";
|
||||
echo "Expected $error but got:\n";
|
||||
var_dump($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
--TEST--
|
||||
Test for inserting and retrieving encrypted data of datetime and smalldatetime types encrypted
|
||||
--DESCRIPTION--
|
||||
Verify that inserting into smalldatetime column might trigger "Datetime field overflow" error
|
||||
Verify that inserting into smalldatetime column (if encrypted) might trigger "Datetime field overflow" error
|
||||
--SKIPIF--
|
||||
<?php require('skipif.inc'); ?>
|
||||
--FILE--
|
||||
|
@ -95,8 +95,9 @@ Verify that inserting into smalldatetime column might trigger "Datetime field ov
|
|||
if ($result) {
|
||||
echo "Inserting invalid values should have failed!\n";
|
||||
} else {
|
||||
$error = ($qualified || AE\isDataEncrypted())? '*Datetime field overflow' : '*The conversion of a varchar data type to a smalldatetime data type resulted in an out-of-range value.';
|
||||
$error = ($qualified)? '*Datetime field overflow' : '*The conversion of a varchar data type to a smalldatetime data type resulted in an out-of-range value.';
|
||||
if (!fnmatch($error, sqlsrv_errors()[0]['message'])) {
|
||||
echo "Expected $error but got:\n";
|
||||
var_dump(sqlsrv_errors());
|
||||
}
|
||||
}
|
||||
|
|
208
test/functional/sqlsrv/sqlsrv_testConnection_unix.phpt
Normal file
208
test/functional/sqlsrv/sqlsrv_testConnection_unix.phpt
Normal file
|
@ -0,0 +1,208 @@
|
|||
--TEST--
|
||||
variety of connection parameters.
|
||||
--DESCRIPTION--
|
||||
The equivalent of sqlsrv_testConnection.phpt but for running outside Windows to verify that GitHub issue 430 is fixed
|
||||
--SKIPIF--
|
||||
<?php
|
||||
require('skipif_azure.inc');
|
||||
|
||||
if ((strtoupper(substr(php_uname('s'), 0, 3)) === 'WIN')) {
|
||||
die("Skip Test on Linux or Mac only.");
|
||||
}
|
||||
?>
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
require 'MsSetup.inc';
|
||||
|
||||
function connect($options=array())
|
||||
{
|
||||
require 'MsSetup.inc';
|
||||
if (!isset($options['UID']) && !isset($options['uid'])) {
|
||||
$options['uid'] = $uid;
|
||||
}
|
||||
if (!isset($options['pwd']) && !isset($options['PWD'])) {
|
||||
$options['pwd'] = $pwd;
|
||||
}
|
||||
if (!isset($options['Database'])) {
|
||||
$options['database'] = $databaseName;
|
||||
}
|
||||
return sqlsrv_connect($server, $options);
|
||||
}
|
||||
|
||||
sqlsrv_configure('WarningsReturnAsErrors', 0);
|
||||
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
|
||||
|
||||
echo "Test sqlsrv_connect with driver injection\n";
|
||||
|
||||
$conn = sqlsrv_connect( $server, array( "UID" => $userName, "PWD" => "$userPassword;Driver={SQL Server Native Client 11.0}}" ));
|
||||
|
||||
if (!$conn) {
|
||||
var_dump(sqlsrv_errors());
|
||||
} else {
|
||||
sqlsrv_close($conn);
|
||||
die("Shouldn't have opened the connection.");
|
||||
}
|
||||
|
||||
echo "Test sqlsrv_connect with driver injection (2)\n";
|
||||
$conn = sqlsrv_connect( $server, array( "UID" => $userName, "PWD" => "{$userPassword};Driver={SQL Server Native Client 11.0}" ));
|
||||
|
||||
if (!$conn) {
|
||||
var_dump(sqlsrv_errors());
|
||||
} else {
|
||||
sqlsrv_close($conn);
|
||||
die("Shouldn't have opened the connection.");
|
||||
}
|
||||
|
||||
echo "Test sqlsrv_connect with driver injection (3)\n";
|
||||
$conn = sqlsrv_connect( $server, array( "UID" => "sa", "PWD" => "{$userPassword}};Driver={SQL Server Native Client 11.0}" ));
|
||||
|
||||
if (!$conn) {
|
||||
var_dump(sqlsrv_errors());
|
||||
} else {
|
||||
sqlsrv_close($conn);
|
||||
die("Shouldn't have opened the connection.");
|
||||
}
|
||||
|
||||
// Test a bunch of options. The Failover_Partner keyword does not work
|
||||
// on Unix, so we replace it with MultiSubnetFailover instead.
|
||||
$conn_options_all = array( "APP" => "PHP Unit Test",
|
||||
"ConnectionPooling" => true,
|
||||
"Database" => $databaseName,
|
||||
"Encrypt" => 0,
|
||||
"LoginTimeout" => 120,
|
||||
"MultipleActiveResultSets" => false,
|
||||
"QuotedId" => false,
|
||||
"TraceOn" => true,
|
||||
"TraceFile" => "trace.odbc",
|
||||
"TransactionIsolation" => SQLSRV_TXN_READ_COMMITTED,
|
||||
"TrustServerCertificate" => 1,
|
||||
"WSID" => "JAYKINT1" );
|
||||
$conn_options_int = array( "APP" => "PHP Unit Test",
|
||||
"ConnectionPooling" => false,
|
||||
"Database" => $databaseName,
|
||||
"Encrypt" => 0,
|
||||
"LoginTimeout" => 120,
|
||||
"MultipleActiveResultSets" => false,
|
||||
"QuotedId" => true,
|
||||
"TraceOn" => true,
|
||||
"TraceFile" => "trace.odbc",
|
||||
"TransactionIsolation" => SQLSRV_TXN_READ_COMMITTED,
|
||||
"TrustServerCertificate" => 1,
|
||||
"WSID" => "JAYKINT1" );
|
||||
|
||||
echo "Test sqlsrv_connect with all options\n";
|
||||
$conn_options_all['MultiSubnetFailover'] = true;
|
||||
$conn = connect($conn_options_all);
|
||||
print_r(sqlsrv_errors()[0]);
|
||||
print_r(sqlsrv_errors()[1]);
|
||||
if ($conn === false) {
|
||||
die(print_r(sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
echo "Test sqlsrv_connect with all options and integrated auth\n";
|
||||
$conn_options_int['MultiSubnetFailover'] = true;
|
||||
$conn = connect($conn_options_int);
|
||||
print_r(sqlsrv_errors()[0]);
|
||||
print_r(sqlsrv_errors()[1]);
|
||||
if ($conn === false) {
|
||||
die(print_r(sqlsrv_errors(), true));
|
||||
}
|
||||
|
||||
sqlsrv_close($conn);
|
||||
echo "Test succeeded.\n";
|
||||
?>
|
||||
--EXPECTREGEX--
|
||||
Test sqlsrv_connect with driver injection
|
||||
array\(1\) \{
|
||||
\[0\]=>
|
||||
array\(6\) \{
|
||||
\[0\]=>
|
||||
string\(5\) "28000"
|
||||
\["SQLSTATE"\]=>
|
||||
string\(5\) "28000"
|
||||
\[1\]=>
|
||||
int\(18456\)
|
||||
\["code"\]=>
|
||||
int\(18456\)
|
||||
\[2\]=>
|
||||
string\(81\) ".*Login failed for user 'sa'."
|
||||
\["message"\]=>
|
||||
string\(81\) ".*Login failed for user 'sa'."
|
||||
\}
|
||||
\}
|
||||
Test sqlsrv_connect with driver injection \(2\)
|
||||
array\(1\) \{
|
||||
\[0\]=>
|
||||
array\(6\) \{
|
||||
\[0\]=>
|
||||
string\(5\) "IMSSP"
|
||||
\["SQLSTATE"\]=>
|
||||
string\(5\) "IMSSP"
|
||||
\[1\]=>
|
||||
int\(-4\)
|
||||
\["code"\]=>
|
||||
int\(-4\)
|
||||
\[2\]=>
|
||||
string\(140\) "An unescaped right brace \(\}\) was found in either the user name or password. All right braces must be escaped with another right brace \(\}\}\)."
|
||||
\["message"\]=>
|
||||
string\(140\) "An unescaped right brace \(\}\) was found in either the user name or password. All right braces must be escaped with another right brace \(\}\}\)."
|
||||
\}
|
||||
\}
|
||||
Test sqlsrv_connect with driver injection \(3\)
|
||||
array\(1\) \{
|
||||
\[0\]=>
|
||||
array\(6\) \{
|
||||
\[0\]=>
|
||||
string\(5\) "IMSSP"
|
||||
\["SQLSTATE"\]=>
|
||||
string\(5\) "IMSSP"
|
||||
\[1\]=>
|
||||
int\(-4\)
|
||||
\["code"\]=>
|
||||
int\(-4\)
|
||||
\[2\]=>
|
||||
string\(140\) "An unescaped right brace \(\}\) was found in either the user name or password. All right braces must be escaped with another right brace \(\}\}\)."
|
||||
\["message"\]=>
|
||||
string\(140\) "An unescaped right brace \(\}\) was found in either the user name or password. All right braces must be escaped with another right brace \(\}\}\)."
|
||||
\}
|
||||
\}
|
||||
Test sqlsrv_connect with all options
|
||||
Array
|
||||
\(
|
||||
\[0\] => 01000
|
||||
\[SQLSTATE\] => 01000
|
||||
\[1\] => 5701
|
||||
\[code\] => 5701
|
||||
\[2\] => .*Changed database context to '.*'.
|
||||
\[message\] => .*Changed database context to '.*'.
|
||||
\)
|
||||
Array
|
||||
\(
|
||||
\[0\] => 01000
|
||||
\[SQLSTATE\] => 01000
|
||||
\[1\] => 5703
|
||||
\[code\] => 5703
|
||||
\[2\] => .*Changed language setting to us_english.
|
||||
\[message\] => .*Changed language setting to us_english.
|
||||
\)
|
||||
Test sqlsrv_connect with all options and integrated auth
|
||||
Array
|
||||
\(
|
||||
\[0\] => 01000
|
||||
\[SQLSTATE\] => 01000
|
||||
\[1\] => 5701
|
||||
\[code\] => 5701
|
||||
\[2\] => .*Changed database context to '.*'.
|
||||
\[message\] => .*Changed database context to '.*'.
|
||||
\)
|
||||
Array
|
||||
\(
|
||||
\[0\] => 01000
|
||||
\[SQLSTATE\] => 01000
|
||||
\[1\] => 5703
|
||||
\[code\] => 5703
|
||||
\[2\] => .*Changed language setting to us_english.
|
||||
\[message\] => .*Changed language setting to us_english.
|
||||
\)
|
||||
Test succeeded.
|
Loading…
Reference in a new issue