Reverted the use of octet length and fixed tests (#1176)
This commit is contained in:
parent
284aca85ce
commit
f02aefd6bd
|
@ -750,25 +750,17 @@ void core_sqlsrv_bind_param( _Inout_ sqlsrv_stmt* stmt, _In_ SQLUSMALLINT param_
|
|||
// 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.
|
||||
// Check SQL_DESC_OCTET_LENGTH of the implementation parameter descriptor (IPD) to distinguish Smalldatetime or Datetime fields from Datetime2(0) or Datetime2(3) fields, as described in
|
||||
// https://docs.microsoft.com/sql/relational-databases/native-client-odbc-date-time/metadata-parameter-and-result
|
||||
// This has to be done before SQLBindParameter()
|
||||
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) {
|
||||
SQLULEN octetLength = 0;
|
||||
SQLINTEGER dummy = 0;
|
||||
|
||||
SQLRETURN r = ::SQLGetDescField(hIpd, param_num + 1, SQL_DESC_OCTET_LENGTH, (SQLPOINTER)&octetLength, 0, &dummy);
|
||||
if (SQL_SUCCEEDED(r)) {
|
||||
// The octet length for datetime2 is 16 but no action required
|
||||
if (octetLength == 8) {
|
||||
r = ::SQLSetDescField(hIpd, param_num + 1, SQL_CA_SS_SERVER_TYPE, (SQLPOINTER)SQL_SS_TYPE_DATETIME, SQL_IS_INTEGER);
|
||||
} else if (octetLength == 4) {
|
||||
r = ::SQLSetDescField(hIpd, param_num + 1, SQL_CA_SS_SERVER_TYPE, (SQLPOINTER)SQL_SS_TYPE_SMALLDATETIME, SQL_IS_INTEGER);
|
||||
}
|
||||
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();
|
||||
|
|
|
@ -63,7 +63,7 @@ try {
|
|||
dropTable($conn, $tableName);
|
||||
|
||||
// Define the column definitions
|
||||
$columns = array('c1' => 'smalldatetime', 'c2' => 'datetime', 'c3' => 'datetime2(0)', 'c4' => 'datetime2(3)');
|
||||
$columns = array('c1' => 'smalldatetime', 'c2' => 'datetime', 'c3' => 'datetime2(0)', 'c4' => 'datetime2(4)');
|
||||
|
||||
if ($qualified) {
|
||||
$tsql = createTableEncryptedQuery($conn, $tableName, $columns);
|
||||
|
@ -76,7 +76,7 @@ try {
|
|||
$val1 = '9999-12-31 23:59:59';
|
||||
$val2 = null;
|
||||
$val3 = null;
|
||||
$val4 = '9999-12-31 23:59:59.999';
|
||||
$val4 = '9999-12-31 23:59:59.9999';
|
||||
|
||||
$tsql = "INSERT INTO $tableName (c1, c2, c3, c4) VALUES (?,?,?,?)";
|
||||
$stmt = $conn->prepare($tsql);
|
||||
|
@ -89,7 +89,7 @@ try {
|
|||
try {
|
||||
$stmt->execute();
|
||||
} catch (PDOException $e) {
|
||||
$error = ($qualified)? '*Datetime field overflow' : '*The conversion of a nvarchar data type to a smalldatetime data type resulted in an out-of-range value.';
|
||||
$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.';
|
||||
if (!fnmatch($error, $e->getMessage())) {
|
||||
echo "The error message is unexpected:\n";
|
||||
var_dump($e->getMessage());
|
||||
|
@ -139,6 +139,6 @@ array(4) {
|
|||
[2]=>
|
||||
string(19) "0001-01-01 01:01:01"
|
||||
[3]=>
|
||||
string(23) "9999-12-31 23:59:59.999"
|
||||
string(24) "9999-12-31 23:59:59.9999"
|
||||
}
|
||||
Done
|
|
@ -65,7 +65,7 @@ Verify that inserting into smalldatetime column might trigger "Datetime field ov
|
|||
dropTable($conn, $tableName);
|
||||
|
||||
// Define the column definitions
|
||||
$columns = array('c1' => 'smalldatetime', 'c2' => 'datetime', 'c3' => 'datetime2(0)', 'c4' => 'datetime2(3)');
|
||||
$columns = array('c1' => 'smalldatetime', 'c2' => 'datetime', 'c3' => 'datetime2(0)', 'c4' => 'datetime2(4)');
|
||||
|
||||
if ($qualified) {
|
||||
$tsql = createTableEncryptedQuery($conn, $tableName, $columns);
|
||||
|
@ -82,7 +82,7 @@ Verify that inserting into smalldatetime column might trigger "Datetime field ov
|
|||
$val1 = '9999-12-31 23:59:59';
|
||||
$val2 = null;
|
||||
$val3 = null;
|
||||
$val4 = '9999-12-31 23:59:59.999';
|
||||
$val4 = '9999-12-31 23:59:59.9999';
|
||||
|
||||
$tsql = "INSERT INTO $tableName (c1, c2, c3, c4) VALUES (?,?,?,?)";
|
||||
$params = array($val1, $val2, $val3, $val4);
|
||||
|
@ -95,7 +95,7 @@ Verify that inserting into smalldatetime column might trigger "Datetime field ov
|
|||
if ($result) {
|
||||
echo "Inserting invalid values should have failed!\n";
|
||||
} else {
|
||||
$error = ($qualified)? '*Datetime field overflow' : '*The conversion of a varchar data type to a smalldatetime data type resulted in an out-of-range value.';
|
||||
$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.';
|
||||
if (!fnmatch($error, sqlsrv_errors()[0]['message'])) {
|
||||
var_dump(sqlsrv_errors());
|
||||
}
|
||||
|
@ -148,6 +148,6 @@ array(4) {
|
|||
["c3"]=>
|
||||
string(19) "0001-01-01 01:01:01"
|
||||
["c4"]=>
|
||||
string(23) "9999-12-31 23:59:59.999"
|
||||
string(24) "9999-12-31 23:59:59.9999"
|
||||
}
|
||||
Done
|
||||
|
|
Loading…
Reference in a new issue