Merge remote-tracking branch 'upstream/AlwaysEncrypted' into ae-tests

This commit is contained in:
David Puglielli 2018-03-09 17:04:57 -08:00
commit 88faf3bd68
25 changed files with 3897 additions and 365 deletions

View file

@ -0,0 +1,134 @@
--TEST--
Test for retrieving encrypted data from binary types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from binary types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any binary type column to PDO::PARAM_STR
2. From any binary type column to PDO::PARAM_LOB
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("binary", "varbinary", "varbinary(max)");
$lengths = array(1, 8, 64, 512, 4000);
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
//create and populate table containing binary(m) or varbinary(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
$inputValues = array(str_repeat("d", $m), str_repeat("r", $m));
insertRow($conn, $tbname, array("c_det" => new BindParamOp(1, $inputValues[0], "PDO::PARAM_LOB", 0, "PDO::SQLSRV_ENCODING_BINARY"),
"c_rand" => new BindParamOp(2, $inputValues[1], "PDO::PARAM_LOB", 0, "PDO::SQLSRV_ENCODING_BINARY")), "prepareBindParam");
// fetch by specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c_det, c_rand FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c_det', $det, constant($pdoParamType));
$stmt->bindColumn('c_rand', $rand, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE: should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!is_null($det) || !is_null($rand)) {
echo "Retrieving $typeFull data as $pdoParamType should not be supported\n";
}
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if (strlen($det) == $m && strlen($rand) == $m) {
echo "****Retrieving $typeFull data as $pdoParamType is supported****\n";
} else {
echo "Retrieving $typeFull data as $pdoParamType fails\n";
}
}
}
// cleanup
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing binary(1):
****Retrieving binary(1) data as PDO::PARAM_STR is supported****
****Retrieving binary(1) data as PDO::PARAM_LOB is supported****
Testing binary(8):
****Retrieving binary(8) data as PDO::PARAM_STR is supported****
****Retrieving binary(8) data as PDO::PARAM_LOB is supported****
Testing binary(64):
****Retrieving binary(64) data as PDO::PARAM_STR is supported****
****Retrieving binary(64) data as PDO::PARAM_LOB is supported****
Testing binary(512):
****Retrieving binary(512) data as PDO::PARAM_STR is supported****
****Retrieving binary(512) data as PDO::PARAM_LOB is supported****
Testing binary(4000):
****Retrieving binary(4000) data as PDO::PARAM_STR is supported****
****Retrieving binary(4000) data as PDO::PARAM_LOB is supported****
Testing varbinary(1):
****Retrieving varbinary(1) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(1) data as PDO::PARAM_LOB is supported****
Testing varbinary(8):
****Retrieving varbinary(8) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(8) data as PDO::PARAM_LOB is supported****
Testing varbinary(64):
****Retrieving varbinary(64) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(64) data as PDO::PARAM_LOB is supported****
Testing varbinary(512):
****Retrieving varbinary(512) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(512) data as PDO::PARAM_LOB is supported****
Testing varbinary(4000):
****Retrieving varbinary(4000) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(4000) data as PDO::PARAM_LOB is supported****
Testing varbinary(max):
****Retrieving varbinary(max) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(max) data as PDO::PARAM_LOB is supported****
Testing varbinary(max):
****Retrieving varbinary(max) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(max) data as PDO::PARAM_LOB is supported****
Testing varbinary(max):
****Retrieving varbinary(max) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(max) data as PDO::PARAM_LOB is supported****
Testing varbinary(max):
****Retrieving varbinary(max) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(max) data as PDO::PARAM_LOB is supported****
Testing varbinary(max):
****Retrieving varbinary(max) data as PDO::PARAM_STR is supported****
****Retrieving varbinary(max) data as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,144 @@
--TEST--
Test for retrieving encrypted data from char types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from char types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any char type column to PDO::PARAM_STR
2. From any char type column to PDO::PARAM_LOB
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("char", "varchar", "varchar(max)");
$lengths = array(1, 8, 64, 512, 4096, 8000);
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
//create and populate table containing char(m) or varchar(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c1", null, "ramdomized"));
createTable($conn, $tbname, $colMetaArr);
$inputValue = str_repeat("d", $m);
insertRow($conn, $tbname, array("c1" => $inputValue));
// fetch by specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c1 FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c1', $c1, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE: should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!empty($det) || !empty($rand)) {
echo "Retrieving $typeFull data as $pdoParamType should not be supported\n";
}
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if (strlen($c1) == $m) {
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
} else {
echo "Retrieving $typeFull as $pdoParamType fails\n";
}
}
}
// cleanup
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing char(1):
****Retrieving char(1) as PDO::PARAM_STR is supported****
****Retrieving char(1) as PDO::PARAM_LOB is supported****
Testing char(8):
****Retrieving char(8) as PDO::PARAM_STR is supported****
****Retrieving char(8) as PDO::PARAM_LOB is supported****
Testing char(64):
****Retrieving char(64) as PDO::PARAM_STR is supported****
****Retrieving char(64) as PDO::PARAM_LOB is supported****
Testing char(512):
****Retrieving char(512) as PDO::PARAM_STR is supported****
****Retrieving char(512) as PDO::PARAM_LOB is supported****
Testing char(4096):
****Retrieving char(4096) as PDO::PARAM_STR is supported****
****Retrieving char(4096) as PDO::PARAM_LOB is supported****
Testing char(8000):
****Retrieving char(8000) as PDO::PARAM_STR is supported****
****Retrieving char(8000) as PDO::PARAM_LOB is supported****
Testing varchar(1):
****Retrieving varchar(1) as PDO::PARAM_STR is supported****
****Retrieving varchar(1) as PDO::PARAM_LOB is supported****
Testing varchar(8):
****Retrieving varchar(8) as PDO::PARAM_STR is supported****
****Retrieving varchar(8) as PDO::PARAM_LOB is supported****
Testing varchar(64):
****Retrieving varchar(64) as PDO::PARAM_STR is supported****
****Retrieving varchar(64) as PDO::PARAM_LOB is supported****
Testing varchar(512):
****Retrieving varchar(512) as PDO::PARAM_STR is supported****
****Retrieving varchar(512) as PDO::PARAM_LOB is supported****
Testing varchar(4096):
****Retrieving varchar(4096) as PDO::PARAM_STR is supported****
****Retrieving varchar(4096) as PDO::PARAM_LOB is supported****
Testing varchar(8000):
****Retrieving varchar(8000) as PDO::PARAM_STR is supported****
****Retrieving varchar(8000) as PDO::PARAM_LOB is supported****
Testing varchar(max):
****Retrieving varchar(max) as PDO::PARAM_STR is supported****
****Retrieving varchar(max) as PDO::PARAM_LOB is supported****
Testing varchar(max):
****Retrieving varchar(max) as PDO::PARAM_STR is supported****
****Retrieving varchar(max) as PDO::PARAM_LOB is supported****
Testing varchar(max):
****Retrieving varchar(max) as PDO::PARAM_STR is supported****
****Retrieving varchar(max) as PDO::PARAM_LOB is supported****
Testing varchar(max):
****Retrieving varchar(max) as PDO::PARAM_STR is supported****
****Retrieving varchar(max) as PDO::PARAM_LOB is supported****
Testing varchar(max):
****Retrieving varchar(max) as PDO::PARAM_STR is supported****
****Retrieving varchar(max) as PDO::PARAM_LOB is supported****
Testing varchar(max):
****Retrieving varchar(max) as PDO::PARAM_STR is supported****
****Retrieving varchar(max) as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,76 @@
--TEST--
Test for retrieving encrypted data from datetime types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from datetime types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any datetime type column to PDO::PARAM_STR
2. From any datetime type column to PDO::PARAM_LOB
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("date", "datetime", "smalldatetime");
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
// create and populate table containing date, datetime or smalldatetime columns
$tbname = "test_" . $dataType;
$colMetaArr = array(new ColumnMeta($dataType, "c_det"), new ColumnMeta($dataType, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
insertRow($conn, $tbname, array("c_det" => $inputValues[0], "c_rand" => $inputValues[1]));
// fetch by specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c_det, c_rand FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c_det', $det, constant($pdoParamType));
$stmt->bindColumn('c_rand', $rand, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE; should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!is_null($det) || !is_null($rand)) {
echo "Retrieving $dataType data as $pdoParamType should not be supported\n";
}
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if (strpos($det, $inputValues[0]) !== false && strpos($rand, $inputValues[1]) !== false) {
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
} else {
echo "Retrieving $dataType as $pdoParamType fails\n";
}
}
}
// cleanup
dropTable($conn, $tbname);
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing date:
****Retrieving date as PDO::PARAM_STR is supported****
****Retrieving date as PDO::PARAM_LOB is supported****
Testing datetime:
****Retrieving datetime as PDO::PARAM_STR is supported****
****Retrieving datetime as PDO::PARAM_LOB is supported****
Testing smalldatetime:
****Retrieving smalldatetime as PDO::PARAM_STR is supported****
****Retrieving smalldatetime as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,149 @@
--TEST--
Test for retrieving encrypted data from datetime types columns with different precisions using PDO::bindColumn
--DESCRIPTION--
Test conversion from datetime types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any datetime type column to PDO::PARAM_STR
2. From any datetime type column to PDO::PARAM_LOB
TODO: cannot insert into a datetime2(0) using the PDO_SQLSRV driver
returns operand type clash error between smalldatetime and datetime2(0)
to see error, uncomment 0 from the $precision array
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
function compareDate($dtout, $dtin, $dataType) {
if ($dataType == "datetimeoffset") {
$dtarr = explode(' ', $dtin);
if (strpos($dtout, $dtarr[0]) !== false && strpos($dtout, $dtarr[1]) !== false && strpos($dtout, $dtarr[2]) !== false) {
return true;
}
} else {
if (strpos($dtout, $dtin) !== false) {
return true;
}
}
return false;
}
$dataTypes = array("datetime2", "datetimeoffset", "time");
$precisions = array(/*0,*/ 1, 2, 4, 7);
$inputValuesInit = array("datetime2" => array("0001-01-01 00:00:00", "9999-12-31 23:59:59"),
"datetimeoffset" => array("0001-01-01 00:00:00 -14:00", "9999-12-31 23:59:59 +14:00"),
"time" => array("00:00:00", "23:59:59"));
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
foreach ($precisions as $m) {
// add $m number of decimal digits to the some input values
$inputValues[0] = $inputValuesInit[$dataType][0];
$inputValues[1] = $inputValuesInit[$dataType][1];
if ($m != 0) {
if ($dataType == "datetime2") {
$inputValues[1] .= "." . str_repeat("9", $m);
} else if ($dataType == "datetimeoffset") {
$dtoffsetPieces = explode(" ", $inputValues[1]);
$inputValues[1] = $dtoffsetPieces[0] . " " . $dtoffsetPieces[1] . "." . str_repeat("9", $m) . " " . $dtoffsetPieces[2];
} else if ($dataType == "time") {
$inputValues[0] .= "." . str_repeat("0", $m);
$inputValues[1] .= "." . str_repeat("9", $m);
}
}
$typeFull = "$dataType($m)";
echo "\nTesting $typeFull:\n";
//create and populate table containing datetime2(m), datetimeoffset(m) or time(m) columns
$tbname = "test_" . $dataType . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
insertRow($conn, $tbname, array("c_det" => $inputValues[0], "c_rand" => $inputValues[1]));
// fetch by specifying PDO::PARAM_ types with PDO:bindColumn
$query = "SELECT c_det, c_rand FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c_det', $det, constant($pdoParamType));
$stmt->bindColumn('c_rand', $rand, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE; should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!is_null($det) || !is_null($rand)) {
echo "Retrieving $typeFull data as $pdoParamType should not be supported\n";
}
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if (compareDate($det, $inputValues[0], $dataType) && compareDate($rand, $inputValues[1], $dataType)) {
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
} else {
echo "Retrieving $typeFull as $pdoParamType fails\n";
}
}
}
// cleanup
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing datetime2(1):
****Retrieving datetime2(1) as PDO::PARAM_STR is supported****
****Retrieving datetime2(1) as PDO::PARAM_LOB is supported****
Testing datetime2(2):
****Retrieving datetime2(2) as PDO::PARAM_STR is supported****
****Retrieving datetime2(2) as PDO::PARAM_LOB is supported****
Testing datetime2(4):
****Retrieving datetime2(4) as PDO::PARAM_STR is supported****
****Retrieving datetime2(4) as PDO::PARAM_LOB is supported****
Testing datetime2(7):
****Retrieving datetime2(7) as PDO::PARAM_STR is supported****
****Retrieving datetime2(7) as PDO::PARAM_LOB is supported****
Testing datetimeoffset(1):
****Retrieving datetimeoffset(1) as PDO::PARAM_STR is supported****
****Retrieving datetimeoffset(1) as PDO::PARAM_LOB is supported****
Testing datetimeoffset(2):
****Retrieving datetimeoffset(2) as PDO::PARAM_STR is supported****
****Retrieving datetimeoffset(2) as PDO::PARAM_LOB is supported****
Testing datetimeoffset(4):
****Retrieving datetimeoffset(4) as PDO::PARAM_STR is supported****
****Retrieving datetimeoffset(4) as PDO::PARAM_LOB is supported****
Testing datetimeoffset(7):
****Retrieving datetimeoffset(7) as PDO::PARAM_STR is supported****
****Retrieving datetimeoffset(7) as PDO::PARAM_LOB is supported****
Testing time(1):
****Retrieving time(1) as PDO::PARAM_STR is supported****
****Retrieving time(1) as PDO::PARAM_LOB is supported****
Testing time(2):
****Retrieving time(2) as PDO::PARAM_STR is supported****
****Retrieving time(2) as PDO::PARAM_LOB is supported****
Testing time(4):
****Retrieving time(4) as PDO::PARAM_STR is supported****
****Retrieving time(4) as PDO::PARAM_LOB is supported****
Testing time(7):
****Retrieving time(7) as PDO::PARAM_STR is supported****
****Retrieving time(7) as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,241 @@
--TEST--
Test for retrieving encrypted data from decimal types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from decimal types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any decimal type column to PDO::PARAM_STR
2. From any decimal type column to PDO::PARAM_LOB
TODO: behavior for teching decimals as PARAM_BOOL and PARAM_INT varies depending on the number being fetched
1. if the number is less than 1, returns 0 (even though the number being fetched is 0.9)
2. 2. if the number is greater than 1 and the number of digits is less than 11, returns the correctly rounded integer (e.g., returns 922 when fetching 922.3)
3. if the number is greater than 1 and the number of digits is greater than 11, returns NULL
need to investigate which should be the correct behavior
for this test, assume to correct behavior is to return NULL
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("decimal", "numeric");
$precisions = array(1 => array(0, 1),
4 => array(0, 1, 4),
16 => array(0, 1, 4, 16),
38 => array(0, 1, 4, 16, 38));
$inputValuesInit = array(92233720368547758089223372036854775808, -92233720368547758089223372036854775808);
$inputPrecision = 38;
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
foreach ($precisions as $m1 => $scales) {
foreach ($scales as $m2) {
// change the number of integers in the input values to be $m1 - $m2
$precDiff = $inputPrecision - ($m1 - $m2);
$inputValues = $inputValuesInit;
foreach ($inputValues as &$inputValue) {
$inputValue = $inputValue / pow(10, $precDiff);
}
// compute the epsilon for comparing doubles
// float in PHP only has a precision of roughtly 14 digits: http://php.net/manual/en/language.types.float.php
$epsilon;
if ($m1 < 14) {
$epsilon = pow(10, $m2 * -1);
} else {
$numint = $m1 - $m2;
if ($numint < 14) {
$epsilon = pow(10, (14 - $numint) * -1);
} else {
$epsilon = pow(10, $numint - 14);
}
}
$typeFull = "$dataType($m1, $m2)";
echo "\nTesting $typeFull:\n";
//create and populate table containing decimal(m1, m2) or numeric(m1, m2) columns
$tbname = "test_" . $dataType . $m1 . $m2;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
insertRow($conn, $tbname, array("c_det" => $inputValues[0], "c_rand" => $inputValues[1]));
// fetch by specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c_det, c_rand FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c_det', $det, constant($pdoParamType));
$stmt->bindColumn('c_rand', $rand, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE; should not work
// assume to correct behavior is to return NULL, see description
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!is_null($det) || !is_null($rand)) {
echo "Retrieving $typeFull data as $pdoParamType should return NULL\n";
}
} else {
if (abs($det - $inputValues[0]) < $epsilon &&
abs($rand - $inputValues[1]) < $epsilon) {
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
} else {
echo "Retrieving $typeFull as $pdoParamType fails\n";
}
}
}
// cleanup
dropTable($conn, $tbname);
}
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing decimal(1, 0):
Retrieving decimal(1, 0) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(1, 0) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(1, 0) as PDO::PARAM_STR is supported****
****Retrieving decimal(1, 0) as PDO::PARAM_LOB is supported****
Testing decimal(1, 1):
Retrieving decimal(1, 1) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(1, 1) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(1, 1) as PDO::PARAM_STR is supported****
****Retrieving decimal(1, 1) as PDO::PARAM_LOB is supported****
Testing decimal(4, 0):
Retrieving decimal(4, 0) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(4, 0) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(4, 0) as PDO::PARAM_STR is supported****
****Retrieving decimal(4, 0) as PDO::PARAM_LOB is supported****
Testing decimal(4, 1):
Retrieving decimal(4, 1) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(4, 1) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(4, 1) as PDO::PARAM_STR is supported****
****Retrieving decimal(4, 1) as PDO::PARAM_LOB is supported****
Testing decimal(4, 4):
Retrieving decimal(4, 4) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(4, 4) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(4, 4) as PDO::PARAM_STR is supported****
****Retrieving decimal(4, 4) as PDO::PARAM_LOB is supported****
Testing decimal(16, 0):
****Retrieving decimal(16, 0) as PDO::PARAM_STR is supported****
****Retrieving decimal(16, 0) as PDO::PARAM_LOB is supported****
Testing decimal(16, 1):
****Retrieving decimal(16, 1) as PDO::PARAM_STR is supported****
****Retrieving decimal(16, 1) as PDO::PARAM_LOB is supported****
Testing decimal(16, 4):
****Retrieving decimal(16, 4) as PDO::PARAM_STR is supported****
****Retrieving decimal(16, 4) as PDO::PARAM_LOB is supported****
Testing decimal(16, 16):
Retrieving decimal(16, 16) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(16, 16) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(16, 16) as PDO::PARAM_STR is supported****
****Retrieving decimal(16, 16) as PDO::PARAM_LOB is supported****
Testing decimal(38, 0):
****Retrieving decimal(38, 0) as PDO::PARAM_STR is supported****
****Retrieving decimal(38, 0) as PDO::PARAM_LOB is supported****
Testing decimal(38, 1):
****Retrieving decimal(38, 1) as PDO::PARAM_STR is supported****
****Retrieving decimal(38, 1) as PDO::PARAM_LOB is supported****
Testing decimal(38, 4):
****Retrieving decimal(38, 4) as PDO::PARAM_STR is supported****
****Retrieving decimal(38, 4) as PDO::PARAM_LOB is supported****
Testing decimal(38, 16):
****Retrieving decimal(38, 16) as PDO::PARAM_STR is supported****
****Retrieving decimal(38, 16) as PDO::PARAM_LOB is supported****
Testing decimal(38, 38):
Retrieving decimal(38, 38) data as PDO::PARAM_BOOL should return NULL
Retrieving decimal(38, 38) data as PDO::PARAM_INT should return NULL
****Retrieving decimal(38, 38) as PDO::PARAM_STR is supported****
****Retrieving decimal(38, 38) as PDO::PARAM_LOB is supported****
Testing numeric(1, 0):
Retrieving numeric(1, 0) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(1, 0) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(1, 0) as PDO::PARAM_STR is supported****
****Retrieving numeric(1, 0) as PDO::PARAM_LOB is supported****
Testing numeric(1, 1):
Retrieving numeric(1, 1) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(1, 1) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(1, 1) as PDO::PARAM_STR is supported****
****Retrieving numeric(1, 1) as PDO::PARAM_LOB is supported****
Testing numeric(4, 0):
Retrieving numeric(4, 0) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(4, 0) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(4, 0) as PDO::PARAM_STR is supported****
****Retrieving numeric(4, 0) as PDO::PARAM_LOB is supported****
Testing numeric(4, 1):
Retrieving numeric(4, 1) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(4, 1) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(4, 1) as PDO::PARAM_STR is supported****
****Retrieving numeric(4, 1) as PDO::PARAM_LOB is supported****
Testing numeric(4, 4):
Retrieving numeric(4, 4) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(4, 4) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(4, 4) as PDO::PARAM_STR is supported****
****Retrieving numeric(4, 4) as PDO::PARAM_LOB is supported****
Testing numeric(16, 0):
****Retrieving numeric(16, 0) as PDO::PARAM_STR is supported****
****Retrieving numeric(16, 0) as PDO::PARAM_LOB is supported****
Testing numeric(16, 1):
****Retrieving numeric(16, 1) as PDO::PARAM_STR is supported****
****Retrieving numeric(16, 1) as PDO::PARAM_LOB is supported****
Testing numeric(16, 4):
****Retrieving numeric(16, 4) as PDO::PARAM_STR is supported****
****Retrieving numeric(16, 4) as PDO::PARAM_LOB is supported****
Testing numeric(16, 16):
Retrieving numeric(16, 16) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(16, 16) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(16, 16) as PDO::PARAM_STR is supported****
****Retrieving numeric(16, 16) as PDO::PARAM_LOB is supported****
Testing numeric(38, 0):
****Retrieving numeric(38, 0) as PDO::PARAM_STR is supported****
****Retrieving numeric(38, 0) as PDO::PARAM_LOB is supported****
Testing numeric(38, 1):
****Retrieving numeric(38, 1) as PDO::PARAM_STR is supported****
****Retrieving numeric(38, 1) as PDO::PARAM_LOB is supported****
Testing numeric(38, 4):
****Retrieving numeric(38, 4) as PDO::PARAM_STR is supported****
****Retrieving numeric(38, 4) as PDO::PARAM_LOB is supported****
Testing numeric(38, 16):
****Retrieving numeric(38, 16) as PDO::PARAM_STR is supported****
****Retrieving numeric(38, 16) as PDO::PARAM_LOB is supported****
Testing numeric(38, 38):
Retrieving numeric(38, 38) data as PDO::PARAM_BOOL should return NULL
Retrieving numeric(38, 38) data as PDO::PARAM_INT should return NULL
****Retrieving numeric(38, 38) as PDO::PARAM_STR is supported****
****Retrieving numeric(38, 38) as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,94 @@
--TEST--
Test for retrieving encrypted data from float types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from float types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any float type column to PDO::PARAM_STR
2. From any float type column to PDO::PARAM_LOB
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataType = "float";
$bits = array(1, 12, 24, 36, 53);
$inputValues = array(9223372036854775808.9223372036854775808, -9223372036854775808.9223372036854775808);
$numint = 19;
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($bits as $m) {
// compute the epsilon for comparing doubles
// when $m <= 24, the precision is 7 digits
// when $m > 24, the precision is 15 digits, but PHP float only supports up to 14 digits
$epsilon;
if ($m <= 24) {
$epsilon = pow(10, $numint - 7);
} else {
$epsilon = pow(10, $numint - 14);
}
$typeFull = "$dataType($m)";
echo "\nTesting $typeFull:\n";
//create and populate table containing float(m) columns
$tbname = "test_" . $dataType . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
insertRow($conn, $tbname, array("c_det" => $inputValues[0], "c_rand" => $inputValues[1]));
// fetchby specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c_det, c_rand FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c_det', $det, constant($pdoParamType));
$stmt->bindColumn('c_rand', $rand, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE; should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!is_null($det) || !is_null($rand)) {
echo "Retriving $typeFull data as $pdoParamType should return NULL\n";
}
} else {
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
} else {
echo "Retrieving $typeFull as $pdoParamType fails\n";
}
}
}
dropTable($conn, $tbname);
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing float(1):
****Retrieving float(1) as PDO::PARAM_STR is supported****
****Retrieving float(1) as PDO::PARAM_LOB is supported****
Testing float(12):
****Retrieving float(12) as PDO::PARAM_STR is supported****
****Retrieving float(12) as PDO::PARAM_LOB is supported****
Testing float(24):
****Retrieving float(24) as PDO::PARAM_STR is supported****
****Retrieving float(24) as PDO::PARAM_LOB is supported****
Testing float(36):
****Retrieving float(36) as PDO::PARAM_STR is supported****
****Retrieving float(36) as PDO::PARAM_LOB is supported****
Testing float(53):
****Retrieving float(53) as PDO::PARAM_STR is supported****
****Retrieving float(53) as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,132 @@
--TEST--
Test for retrieving encrypted data from nchar types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from nchar types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any nchar type column to PDO::PARAM_STR
2. From any nchar type column to PDO::PARAM_LOB
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("nchar", "nvarchar", "nvarchar(max)");
$lengths = array(1, 8, 64, 512, 4000);
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
//create and populate table containing nchar(m) or nvarchar(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c1"));
createTable($conn, $tbname, $colMetaArr);
$inputValue = str_repeat("d", $m);
insertRow($conn, $tbname, array("c1" => $inputValue));
// fetch by specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c1 FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c1', $c1, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_NULL or PDO::PARAM_INT
// with or without AE: should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_NULL" || $pdoParamType == "PDO::PARAM_INT") {
if (!empty($det) || !empty($rand)) {
echo "Retrieving $typeFull data as $pdoParamType should not be supported\n";
}
// check the case when fetching as PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if (strlen($c1) == $m) {
echo "****Retrieving $typeFull as $pdoParamType is supported****\n";
} else {
echo "Retrieving $typeFull as $pdoParamType fails\n";
}
}
}
// cleanup
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing nchar(1):
****Retrieving nchar(1) as PDO::PARAM_STR is supported****
****Retrieving nchar(1) as PDO::PARAM_LOB is supported****
Testing nchar(8):
****Retrieving nchar(8) as PDO::PARAM_STR is supported****
****Retrieving nchar(8) as PDO::PARAM_LOB is supported****
Testing nchar(64):
****Retrieving nchar(64) as PDO::PARAM_STR is supported****
****Retrieving nchar(64) as PDO::PARAM_LOB is supported****
Testing nchar(512):
****Retrieving nchar(512) as PDO::PARAM_STR is supported****
****Retrieving nchar(512) as PDO::PARAM_LOB is supported****
Testing nchar(4000):
****Retrieving nchar(4000) as PDO::PARAM_STR is supported****
****Retrieving nchar(4000) as PDO::PARAM_LOB is supported****
Testing nvarchar(1):
****Retrieving nvarchar(1) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(1) as PDO::PARAM_LOB is supported****
Testing nvarchar(8):
****Retrieving nvarchar(8) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(8) as PDO::PARAM_LOB is supported****
Testing nvarchar(64):
****Retrieving nvarchar(64) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(64) as PDO::PARAM_LOB is supported****
Testing nvarchar(512):
****Retrieving nvarchar(512) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(512) as PDO::PARAM_LOB is supported****
Testing nvarchar(4000):
****Retrieving nvarchar(4000) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(4000) as PDO::PARAM_LOB is supported****
Testing nvarchar(max):
****Retrieving nvarchar(max) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(max) as PDO::PARAM_LOB is supported****
Testing nvarchar(max):
****Retrieving nvarchar(max) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(max) as PDO::PARAM_LOB is supported****
Testing nvarchar(max):
****Retrieving nvarchar(max) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(max) as PDO::PARAM_LOB is supported****
Testing nvarchar(max):
****Retrieving nvarchar(max) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(max) as PDO::PARAM_LOB is supported****
Testing nvarchar(max):
****Retrieving nvarchar(max) as PDO::PARAM_STR is supported****
****Retrieving nvarchar(max) as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,128 @@
--TEST--
Test for retrieving encrypted data from numeric types columns using PDO::bindColumn
--DESCRIPTION--
Test conversion from numeric types column to output of PDO::PARAM types
With or without AE, conversion works if:
1. From any numeric type except for bigint column to PDO::PARAM_BOOL
2. From any numeric type except for bigint column to PDO::PARAM_INT
3. From any numeric type column to PDO::PARAM_STR
4. From any numeric type column to PDO::PARAM_LOB
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array( "bit", "tinyint", "smallint", "int", "bigint", "real");
$epsilon = 1;
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
// create and populate table containing bit, tinyint, smallint, int, bigint, or real columns
$tbname = "test_" . $dataType;
$colMetaArr = array(new ColumnMeta($dataType, "c_det"), new ColumnMeta($dataType, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
insertRow($conn, $tbname, array("c_det" => $inputValues[0], "c_rand" => $inputValues[1]));
// fetch by specifying PDO::PARAM_ types with PDO::bindColumn
$query = "SELECT c_det, c_rand FROM $tbname";
foreach ($pdoParamTypes as $pdoParamType) {
$det = "";
$rand = "";
$stmt = $conn->prepare($query);
$stmt->execute();
$stmt->bindColumn('c_det', $det, constant($pdoParamType));
$stmt->bindColumn('c_rand', $rand, constant($pdoParamType));
$row = $stmt->fetch(PDO::FETCH_BOUND);
// check the case when fetching as PDO::PARAM_NULL
// with or without AE: should not work
if ($pdoParamType == "PDO::PARAM_NULL") {
if (!is_null($det) || !is_null($rand)) {
echo "Retrieving $dataType data as $pdoParamType should not be supported\n";
}
// check the case when fetching as PDO::PARAM_BOOL or PDO::PARAM_INT
// with or without AE: should only not work with bigint
} else if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_INT") {
if ($dataType == "bigint") {
if (!is_null($det) || !is_null($rand)) {
echo "Retrieving $dataType data as $pdoParamType should not be supported\n";
}
} else if ($dataType == "real") {
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
} else {
echo "Retrieving $dataType as $pdoParamType fails\n";
}
} else {
if ($det == $inputValues[0] && $rand == $inputValues[1]) {
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
} else {
echo "Retrieving $dataType as $pdoParamType fails\n";
}
}
// check the case when fetching as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if ($dataType == "real") {
if (abs($det - $inputValues[0]) < $epsilon && abs($rand - $inputValues[1]) < $epsilon) {
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
} else {
echo "Retrieving $dataType as $pdoParamType fails\n";
}
} else {
if ($det == $inputValues[0] && $rand == $inputValues[1]) {
echo "****Retrieving $dataType as $pdoParamType is supported****\n";
} else {
echo "Retrieving $dataType as $pdoParamType fails\n";
}
}
}
}
dropTable($conn, $tbname);
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing bit:
****Retrieving bit as PDO::PARAM_BOOL is supported****
****Retrieving bit as PDO::PARAM_INT is supported****
****Retrieving bit as PDO::PARAM_STR is supported****
****Retrieving bit as PDO::PARAM_LOB is supported****
Testing tinyint:
****Retrieving tinyint as PDO::PARAM_BOOL is supported****
****Retrieving tinyint as PDO::PARAM_INT is supported****
****Retrieving tinyint as PDO::PARAM_STR is supported****
****Retrieving tinyint as PDO::PARAM_LOB is supported****
Testing smallint:
****Retrieving smallint as PDO::PARAM_BOOL is supported****
****Retrieving smallint as PDO::PARAM_INT is supported****
****Retrieving smallint as PDO::PARAM_STR is supported****
****Retrieving smallint as PDO::PARAM_LOB is supported****
Testing int:
****Retrieving int as PDO::PARAM_BOOL is supported****
****Retrieving int as PDO::PARAM_INT is supported****
****Retrieving int as PDO::PARAM_STR is supported****
****Retrieving int as PDO::PARAM_LOB is supported****
Testing bigint:
****Retrieving bigint as PDO::PARAM_STR is supported****
****Retrieving bigint as PDO::PARAM_LOB is supported****
Testing real:
****Retrieving real as PDO::PARAM_BOOL is supported****
****Retrieving real as PDO::PARAM_INT is supported****
****Retrieving real as PDO::PARAM_STR is supported****
****Retrieving real as PDO::PARAM_LOB is supported****

View file

@ -0,0 +1,159 @@
--TEST--
Test for inserting encrypted data into binary types columns with different sizes
--DESCRIPTION--
Test conversions between different binary types of different sizes
With or without Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_STR to a any binary column
2. From input of PDO::PARAM_LOB to a any binary column
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("binary", "varbinary", "varbinary(max)");
$lengths = array(2, 8, 64, 512, 4000);
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
// create table containing binary(m) or varbinary(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
$inputValues = array(str_repeat("d", $m), str_repeat("r", $m));
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
$r;
if ($pdoParamType == 'PDO::PARAM_STR' || $pdoParamType == 'PDO::PARAM_LOB') {
$stmt = insertRow($conn, $tbname, array("c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType, 0, "PDO::SQLSRV_ENCODING_BINARY"),
"c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType, 0, "PDO::SQLSRV_ENCODING_BINARY")), "prepareBindParam", $r);
} else {
$stmt = insertRow($conn, $tbname, array("c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
}
// check the case when inserting as PDO::PARAM_BOOL or PDO::PARAM_INT
// with or without AE: should not work
if ($pdoParamType == "PDO::PARAM_BOOL" || $pdoParamType == "PDO::PARAM_INT") {
if ($r !== false) {
echo "Conversion from $pdoParamType to $typeFull should not be supported\n";
}
// check the case when inserting as PDO::PARAM_NULL
// with AE: NULL is inserted
// without AE: insertion fails
} elseif ($pdoParamType == "PDO::PARAM_NULL") {
if (isAEConnected()) {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c_det']) && !is_null($row['c_rand'])) {
echo "Conversion from $pdoParamType to $typeFull should insert NULL\n";
}
}
} else {
if ($r !== false) {
echo "Conversion from $pdoParamType to $typeFull should not be supported\n";
}
}
// check the case when inserting as PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (strlen($row['c_det']) == $m && strlen($row['c_rand']) == $m) {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
} else {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
}
}
// cleanup
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing binary(2):
****Conversion from PDO::PARAM_STR to binary(2) is supported****
****Conversion from PDO::PARAM_LOB to binary(2) is supported****
Testing binary(8):
****Conversion from PDO::PARAM_STR to binary(8) is supported****
****Conversion from PDO::PARAM_LOB to binary(8) is supported****
Testing binary(64):
****Conversion from PDO::PARAM_STR to binary(64) is supported****
****Conversion from PDO::PARAM_LOB to binary(64) is supported****
Testing binary(512):
****Conversion from PDO::PARAM_STR to binary(512) is supported****
****Conversion from PDO::PARAM_LOB to binary(512) is supported****
Testing binary(4000):
****Conversion from PDO::PARAM_STR to binary(4000) is supported****
****Conversion from PDO::PARAM_LOB to binary(4000) is supported****
Testing varbinary(2):
****Conversion from PDO::PARAM_STR to varbinary(2) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(2) is supported****
Testing varbinary(8):
****Conversion from PDO::PARAM_STR to varbinary(8) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(8) is supported****
Testing varbinary(64):
****Conversion from PDO::PARAM_STR to varbinary(64) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(64) is supported****
Testing varbinary(512):
****Conversion from PDO::PARAM_STR to varbinary(512) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(512) is supported****
Testing varbinary(4000):
****Conversion from PDO::PARAM_STR to varbinary(4000) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(4000) is supported****
Testing varbinary(max):
****Conversion from PDO::PARAM_STR to varbinary(max) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from PDO::PARAM_STR to varbinary(max) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from PDO::PARAM_STR to varbinary(max) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from PDO::PARAM_STR to varbinary(max) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from PDO::PARAM_STR to varbinary(max) is supported****
****Conversion from PDO::PARAM_LOB to varbinary(max) is supported****

View file

@ -0,0 +1,187 @@
--TEST--
Test for inserting encrypted data into char types columns with different sizes
--DESCRIPTION--
Test conversions between different char types of different sizes
With or without Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a any char column
2. From input of PDO::PARAM_INT to a any char column
3. From input of PDO::PARAM_STR to a any char column
4. From input of PDO::PARAM_LOB to a any char column
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("char", "varchar", "varchar(max)");
$lengths = array(1, 8, 64, 512, 4096, 8000);
try {
$conn = connect();
foreach ($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
//create table containing char(m) or varchar(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c1", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
$input = str_repeat("d", $m);
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
$r;
$stmt = insertRow($conn, $tbname, array( "c1" => new BindParamOp(1, $input, $pdoParamType)), "prepareBindParam", $r);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c1 FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c1'])) {
echo "Conversion from $pdoParamType to $typeFull should insert NULL\n";
}
}
// check the case when inserting as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO{{PARAM_LOB
// with or without AE: should work
} else {
$sql = "SELECT c1 FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (strlen($row['c1']) == $m) {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
} else {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
}
// cleanup
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing char(1):
****Conversion from PDO::PARAM_BOOL to char(1) is supported****
****Conversion from PDO::PARAM_INT to char(1) is supported****
****Conversion from PDO::PARAM_STR to char(1) is supported****
****Conversion from PDO::PARAM_LOB to char(1) is supported****
Testing char(8):
****Conversion from PDO::PARAM_BOOL to char(8) is supported****
****Conversion from PDO::PARAM_INT to char(8) is supported****
****Conversion from PDO::PARAM_STR to char(8) is supported****
****Conversion from PDO::PARAM_LOB to char(8) is supported****
Testing char(64):
****Conversion from PDO::PARAM_BOOL to char(64) is supported****
****Conversion from PDO::PARAM_INT to char(64) is supported****
****Conversion from PDO::PARAM_STR to char(64) is supported****
****Conversion from PDO::PARAM_LOB to char(64) is supported****
Testing char(512):
****Conversion from PDO::PARAM_BOOL to char(512) is supported****
****Conversion from PDO::PARAM_INT to char(512) is supported****
****Conversion from PDO::PARAM_STR to char(512) is supported****
****Conversion from PDO::PARAM_LOB to char(512) is supported****
Testing char(4096):
****Conversion from PDO::PARAM_BOOL to char(4096) is supported****
****Conversion from PDO::PARAM_INT to char(4096) is supported****
****Conversion from PDO::PARAM_STR to char(4096) is supported****
****Conversion from PDO::PARAM_LOB to char(4096) is supported****
Testing char(8000):
****Conversion from PDO::PARAM_BOOL to char(8000) is supported****
****Conversion from PDO::PARAM_INT to char(8000) is supported****
****Conversion from PDO::PARAM_STR to char(8000) is supported****
****Conversion from PDO::PARAM_LOB to char(8000) is supported****
Testing varchar(1):
****Conversion from PDO::PARAM_BOOL to varchar(1) is supported****
****Conversion from PDO::PARAM_INT to varchar(1) is supported****
****Conversion from PDO::PARAM_STR to varchar(1) is supported****
****Conversion from PDO::PARAM_LOB to varchar(1) is supported****
Testing varchar(8):
****Conversion from PDO::PARAM_BOOL to varchar(8) is supported****
****Conversion from PDO::PARAM_INT to varchar(8) is supported****
****Conversion from PDO::PARAM_STR to varchar(8) is supported****
****Conversion from PDO::PARAM_LOB to varchar(8) is supported****
Testing varchar(64):
****Conversion from PDO::PARAM_BOOL to varchar(64) is supported****
****Conversion from PDO::PARAM_INT to varchar(64) is supported****
****Conversion from PDO::PARAM_STR to varchar(64) is supported****
****Conversion from PDO::PARAM_LOB to varchar(64) is supported****
Testing varchar(512):
****Conversion from PDO::PARAM_BOOL to varchar(512) is supported****
****Conversion from PDO::PARAM_INT to varchar(512) is supported****
****Conversion from PDO::PARAM_STR to varchar(512) is supported****
****Conversion from PDO::PARAM_LOB to varchar(512) is supported****
Testing varchar(4096):
****Conversion from PDO::PARAM_BOOL to varchar(4096) is supported****
****Conversion from PDO::PARAM_INT to varchar(4096) is supported****
****Conversion from PDO::PARAM_STR to varchar(4096) is supported****
****Conversion from PDO::PARAM_LOB to varchar(4096) is supported****
Testing varchar(8000):
****Conversion from PDO::PARAM_BOOL to varchar(8000) is supported****
****Conversion from PDO::PARAM_INT to varchar(8000) is supported****
****Conversion from PDO::PARAM_STR to varchar(8000) is supported****
****Conversion from PDO::PARAM_LOB to varchar(8000) is supported****
Testing varchar(max):
****Conversion from PDO::PARAM_BOOL to varchar(max) is supported****
****Conversion from PDO::PARAM_INT to varchar(max) is supported****
****Conversion from PDO::PARAM_STR to varchar(max) is supported****
****Conversion from PDO::PARAM_LOB to varchar(max) is supported****
Testing varchar(max):
****Conversion from PDO::PARAM_BOOL to varchar(max) is supported****
****Conversion from PDO::PARAM_INT to varchar(max) is supported****
****Conversion from PDO::PARAM_STR to varchar(max) is supported****
****Conversion from PDO::PARAM_LOB to varchar(max) is supported****
Testing varchar(max):
****Conversion from PDO::PARAM_BOOL to varchar(max) is supported****
****Conversion from PDO::PARAM_INT to varchar(max) is supported****
****Conversion from PDO::PARAM_STR to varchar(max) is supported****
****Conversion from PDO::PARAM_LOB to varchar(max) is supported****
Testing varchar(max):
****Conversion from PDO::PARAM_BOOL to varchar(max) is supported****
****Conversion from PDO::PARAM_INT to varchar(max) is supported****
****Conversion from PDO::PARAM_STR to varchar(max) is supported****
****Conversion from PDO::PARAM_LOB to varchar(max) is supported****
Testing varchar(max):
****Conversion from PDO::PARAM_BOOL to varchar(max) is supported****
****Conversion from PDO::PARAM_INT to varchar(max) is supported****
****Conversion from PDO::PARAM_STR to varchar(max) is supported****
****Conversion from PDO::PARAM_LOB to varchar(max) is supported****
Testing varchar(max):
****Conversion from PDO::PARAM_BOOL to varchar(max) is supported****
****Conversion from PDO::PARAM_INT to varchar(max) is supported****
****Conversion from PDO::PARAM_STR to varchar(max) is supported****
****Conversion from PDO::PARAM_LOB to varchar(max) is supported****

View file

@ -1,7 +1,12 @@
--TEST--
Test for inserting and retrieving encrypted data of datetime types
Test for inserting encrypted data into datetime types columns
--DESCRIPTION--
Use PDOstatement::bindParam with all PDO::PARAM_ types
Test conversions between different datetime types
With or without Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a any datetime column
2. From input of PDO::PARAM_INT to a any datetime column
3. From input of PDO::PARAM_STR to a any datetime column
4. From input of PDO::PARAM_LOB to a any datetime column
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
@ -9,28 +14,48 @@ Use PDOstatement::bindParam with all PDO::PARAM_ types
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array( "date", "datetime", "datetime2", "smalldatetime", "time", "datetimeoffset" );
$dataTypes = array( "date", "datetime", "smalldatetime");
try {
$conn = connect();
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
// create table
$tbname = getTableName();
// create table containing date, datetime or smalldatetime columns
$tbname = "test_" . $dataType;
$colMetaArr = array( new ColumnMeta($dataType, "c_det"), new ColumnMeta($dataType, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
// prepare statement for inserting into table
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
// insert a row
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
$r;
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
if ($r === false) {
isIncompatibleTypesError($stmt, $dataType, $pdoParamType);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c_det']) || !is_null($row['c_rand'])) {
echo "Conversion from $pdoParamType to $dataType should insert NULL\n";
}
}
// check the case when inserting as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
echo "****PDO param type $pdoParamType is compatible with encrypted $dataType****\n";
fetchAll($conn, $tbname);
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (strpos($row['c_det'], $inputValues[0]) !== false && strpos($row['c_rand'], $inputValues[1]) !== false) {
echo "****Conversion from $pdoParamType to $dataType is supported****\n";
} else {
echo "Conversion from $pdoParamType to $dataType causes data corruption\n";
}
}
$conn->query("TRUNCATE TABLE $tbname");
}
@ -43,105 +68,20 @@ try {
}
?>
--EXPECT--
Testing date:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted date****
c_det: 0001-01-01
c_rand: 9999-12-31
****PDO param type PDO::PARAM_NULL is compatible with encrypted date****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted date****
c_det: 0001-01-01
c_rand: 9999-12-31
****PDO param type PDO::PARAM_STR is compatible with encrypted date****
c_det: 0001-01-01
c_rand: 9999-12-31
****PDO param type PDO::PARAM_LOB is compatible with encrypted date****
c_det: 0001-01-01
c_rand: 9999-12-31
****Conversion from PDO::PARAM_BOOL to date is supported****
****Conversion from PDO::PARAM_INT to date is supported****
****Conversion from PDO::PARAM_STR to date is supported****
****Conversion from PDO::PARAM_LOB to date is supported****
Testing datetime:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted datetime****
c_det: 1753-01-01 00:00:00.000
c_rand: 9999-12-31 23:59:59.997
****PDO param type PDO::PARAM_NULL is compatible with encrypted datetime****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted datetime****
c_det: 1753-01-01 00:00:00.000
c_rand: 9999-12-31 23:59:59.997
****PDO param type PDO::PARAM_STR is compatible with encrypted datetime****
c_det: 1753-01-01 00:00:00.000
c_rand: 9999-12-31 23:59:59.997
****PDO param type PDO::PARAM_LOB is compatible with encrypted datetime****
c_det: 1753-01-01 00:00:00.000
c_rand: 9999-12-31 23:59:59.997
Testing datetime2:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted datetime2****
c_det: 0001-01-01 00:00:00.0000000
c_rand: 9999-12-31 23:59:59.9999999
****PDO param type PDO::PARAM_NULL is compatible with encrypted datetime2****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted datetime2****
c_det: 0001-01-01 00:00:00.0000000
c_rand: 9999-12-31 23:59:59.9999999
****PDO param type PDO::PARAM_STR is compatible with encrypted datetime2****
c_det: 0001-01-01 00:00:00.0000000
c_rand: 9999-12-31 23:59:59.9999999
****PDO param type PDO::PARAM_LOB is compatible with encrypted datetime2****
c_det: 0001-01-01 00:00:00.0000000
c_rand: 9999-12-31 23:59:59.9999999
****Conversion from PDO::PARAM_BOOL to datetime is supported****
****Conversion from PDO::PARAM_INT to datetime is supported****
****Conversion from PDO::PARAM_STR to datetime is supported****
****Conversion from PDO::PARAM_LOB to datetime is supported****
Testing smalldatetime:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted smalldatetime****
c_det: 1900-01-01 00:00:00
c_rand: 2079-06-05 23:59:00
****PDO param type PDO::PARAM_NULL is compatible with encrypted smalldatetime****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted smalldatetime****
c_det: 1900-01-01 00:00:00
c_rand: 2079-06-05 23:59:00
****PDO param type PDO::PARAM_STR is compatible with encrypted smalldatetime****
c_det: 1900-01-01 00:00:00
c_rand: 2079-06-05 23:59:00
****PDO param type PDO::PARAM_LOB is compatible with encrypted smalldatetime****
c_det: 1900-01-01 00:00:00
c_rand: 2079-06-05 23:59:00
Testing time:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted time****
c_det: 00:00:00.0000000
c_rand: 23:59:59.9999999
****PDO param type PDO::PARAM_NULL is compatible with encrypted time****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted time****
c_det: 00:00:00.0000000
c_rand: 23:59:59.9999999
****PDO param type PDO::PARAM_STR is compatible with encrypted time****
c_det: 00:00:00.0000000
c_rand: 23:59:59.9999999
****PDO param type PDO::PARAM_LOB is compatible with encrypted time****
c_det: 00:00:00.0000000
c_rand: 23:59:59.9999999
Testing datetimeoffset:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted datetimeoffset****
c_det: 0001-01-01 00:00:00.0000000 -14:00
c_rand: 9999-12-31 23:59:59.9999999 +14:00
****PDO param type PDO::PARAM_NULL is compatible with encrypted datetimeoffset****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted datetimeoffset****
c_det: 0001-01-01 00:00:00.0000000 -14:00
c_rand: 9999-12-31 23:59:59.9999999 +14:00
****PDO param type PDO::PARAM_STR is compatible with encrypted datetimeoffset****
c_det: 0001-01-01 00:00:00.0000000 -14:00
c_rand: 9999-12-31 23:59:59.9999999 +14:00
****PDO param type PDO::PARAM_LOB is compatible with encrypted datetimeoffset****
c_det: 0001-01-01 00:00:00.0000000 -14:00
c_rand: 9999-12-31 23:59:59.9999999 +14:00
****Conversion from PDO::PARAM_BOOL to smalldatetime is supported****
****Conversion from PDO::PARAM_INT to smalldatetime is supported****
****Conversion from PDO::PARAM_STR to smalldatetime is supported****
****Conversion from PDO::PARAM_LOB to smalldatetime is supported****

View file

@ -0,0 +1,175 @@
--TEST--
Test for inserting encrypted data into datetime types with different precisions columns
--DESCRIPTION--
Test conversions between different datetime types
With or without Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a any datetime column
2. From input of PDO::PARAM_INT to a any datetime column
3. From input of PDO::PARAM_STR to a any datetime column
4. From input of PDO::PARAM_LOB to a any datetime column
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
function compareDate($dtout, $dtin, $dataType) {
if ($dataType == "datetimeoffset") {
$dtarr = explode(' ', $dtin);
if (strpos($dtout, $dtarr[0]) !== false && strpos($dtout, $dtarr[1]) !== false && strpos($dtout, $dtarr[2]) !== false) {
return true;
}
} else {
if (strpos($dtout, $dtin) !== false) {
return true;
}
}
return false;
}
$dataTypes = array("datetime2", "datetimeoffset", "time");
$precisions = array(/*0,*/ 1, 2, 4, 7);
$inputValuesInit = array("datetime2" => array("0001-01-01 00:00:00", "9999-12-31 23:59:59"),
"datetimeoffset" => array("0001-01-01 00:00:00 -14:00", "9999-12-31 23:59:59 +14:00"),
"time" => array("00:00:00", "23:59:59"));
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
foreach ($precisions as $m) {
// add $m number of decimal digits to the some input values
$inputValues[0] = $inputValuesInit[$dataType][0];
$inputValues[1] = $inputValuesInit[$dataType][1];
if ($m != 0) {
if ($dataType == "datetime2") {
$inputValues[1] .= "." . str_repeat("9", $m);
} else if ($dataType == "datetimeoffset") {
$dtoffsetPieces = explode(" ", $inputValues[1]);
$inputValues[1] = $dtoffsetPieces[0] . " " . $dtoffsetPieces[1] . "." . str_repeat("9", $m) . " " . $dtoffsetPieces[2];
} else if ($dataType == "time") {
$inputValues[0] .= "." . str_repeat("0", $m);
$inputValues[1] .= "." . str_repeat("9", $m);
}
}
$typeFull = "$dataType($m)";
echo "\nTesting $typeFull:\n";
//create table containing datetime2(m), datetimeoffset(m), or time(m) columns
$tbname = "test_" . $dataType . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
$r;
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c_det']) || !is_null($row['c_rand'])) {
echo "Conversion from $pdoParamType to $typeFull should insert NULL\n";
}
}
// check the case when inserting as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (compareDate($row['c_det'], $inputValues[0], $dataType) && compareDate($row['c_rand'], $inputValues[1], $dataType)) {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
} else {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
}
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing datetime2(1):
****Conversion from PDO::PARAM_BOOL to datetime2(1) is supported****
****Conversion from PDO::PARAM_INT to datetime2(1) is supported****
****Conversion from PDO::PARAM_STR to datetime2(1) is supported****
****Conversion from PDO::PARAM_LOB to datetime2(1) is supported****
Testing datetime2(2):
****Conversion from PDO::PARAM_BOOL to datetime2(2) is supported****
****Conversion from PDO::PARAM_INT to datetime2(2) is supported****
****Conversion from PDO::PARAM_STR to datetime2(2) is supported****
****Conversion from PDO::PARAM_LOB to datetime2(2) is supported****
Testing datetime2(4):
****Conversion from PDO::PARAM_BOOL to datetime2(4) is supported****
****Conversion from PDO::PARAM_INT to datetime2(4) is supported****
****Conversion from PDO::PARAM_STR to datetime2(4) is supported****
****Conversion from PDO::PARAM_LOB to datetime2(4) is supported****
Testing datetime2(7):
****Conversion from PDO::PARAM_BOOL to datetime2(7) is supported****
****Conversion from PDO::PARAM_INT to datetime2(7) is supported****
****Conversion from PDO::PARAM_STR to datetime2(7) is supported****
****Conversion from PDO::PARAM_LOB to datetime2(7) is supported****
Testing datetimeoffset(1):
****Conversion from PDO::PARAM_BOOL to datetimeoffset(1) is supported****
****Conversion from PDO::PARAM_INT to datetimeoffset(1) is supported****
****Conversion from PDO::PARAM_STR to datetimeoffset(1) is supported****
****Conversion from PDO::PARAM_LOB to datetimeoffset(1) is supported****
Testing datetimeoffset(2):
****Conversion from PDO::PARAM_BOOL to datetimeoffset(2) is supported****
****Conversion from PDO::PARAM_INT to datetimeoffset(2) is supported****
****Conversion from PDO::PARAM_STR to datetimeoffset(2) is supported****
****Conversion from PDO::PARAM_LOB to datetimeoffset(2) is supported****
Testing datetimeoffset(4):
****Conversion from PDO::PARAM_BOOL to datetimeoffset(4) is supported****
****Conversion from PDO::PARAM_INT to datetimeoffset(4) is supported****
****Conversion from PDO::PARAM_STR to datetimeoffset(4) is supported****
****Conversion from PDO::PARAM_LOB to datetimeoffset(4) is supported****
Testing datetimeoffset(7):
****Conversion from PDO::PARAM_BOOL to datetimeoffset(7) is supported****
****Conversion from PDO::PARAM_INT to datetimeoffset(7) is supported****
****Conversion from PDO::PARAM_STR to datetimeoffset(7) is supported****
****Conversion from PDO::PARAM_LOB to datetimeoffset(7) is supported****
Testing time(1):
****Conversion from PDO::PARAM_BOOL to time(1) is supported****
****Conversion from PDO::PARAM_INT to time(1) is supported****
****Conversion from PDO::PARAM_STR to time(1) is supported****
****Conversion from PDO::PARAM_LOB to time(1) is supported****
Testing time(2):
****Conversion from PDO::PARAM_BOOL to time(2) is supported****
****Conversion from PDO::PARAM_INT to time(2) is supported****
****Conversion from PDO::PARAM_STR to time(2) is supported****
****Conversion from PDO::PARAM_LOB to time(2) is supported****
Testing time(4):
****Conversion from PDO::PARAM_BOOL to time(4) is supported****
****Conversion from PDO::PARAM_INT to time(4) is supported****
****Conversion from PDO::PARAM_STR to time(4) is supported****
****Conversion from PDO::PARAM_LOB to time(4) is supported****
Testing time(7):
****Conversion from PDO::PARAM_BOOL to time(7) is supported****
****Conversion from PDO::PARAM_INT to time(7) is supported****
****Conversion from PDO::PARAM_STR to time(7) is supported****
****Conversion from PDO::PARAM_LOB to time(7) is supported****

View file

@ -0,0 +1,294 @@
--TEST--
Test for inserting encrypted data into decimal types columns
--DESCRIPTION--
Test conversions between different decimal types
With Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a any decimal column
2. From input of PDO::PARAM_INT to a any decimal column
3. From input of PDO::PARAM_STR to a any decimal column
4. From input of PDO::PARAM_LOB to a any decimal column
Without Always Encrypted, all of the above should work except for:
1. From input of PDO::PARAM_STR to a decimal column and the input has more than 14 digits to the left of the decimal
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("decimal", "numeric");
$precisions = array(1 => array(0, 1),
4 => array(0, 1, 4),
16 => array(0, 1, 4, 16),
38 => array(0, 1, 4, 16, 38));
$inputValuesInit = array(92233720368547758089223372036854775808, -92233720368547758089223372036854775808);
$inputPrecision = 38;
try {
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
foreach ($precisions as $m1 => $scales) {
foreach ($scales as $m2) {
// change the number of integers in the input values to be $m1 - $m2
$precDiff = $inputPrecision - ($m1 - $m2);
$inputValues = $inputValuesInit;
foreach ($inputValues as &$inputValue) {
$inputValue = $inputValue / pow(10, $precDiff);
}
// compute the epsilon for comparing doubles
// float in PHP only has a precision of roughtly 14 digits: http://php.net/manual/en/language.types.float.php
$epsilon;
if ($m1 < 14) {
$epsilon = pow(10, $m2 * -1);
} else {
$numint = $m1 - $m2;
if ($numint < 14) {
$epsilon = pow(10, (14 - $numint) * -1);
} else {
$epsilon = pow(10, $numint - 14);
}
}
$typeFull = "$dataType($m1, $m2)";
echo "\nTesting $typeFull:\n";
// create table containing decimal(m1, m2) or numeric(m1, m2) columns
$tbname = "test_" . $dataType . $m1 . $m2;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
$r;
$stmt = insertRow($conn, $tbname, array("c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c_det']) || !is_null($row['c_rand'])) {
echo "NULL should have been inserted with $pdoParamType\n";
}
}
// check the case when inserting as PDO::PARAM_STR and the input has more than 14 digits to the left of the decimal
// with AE: should work
// without AE: should not work
// when the input has greater than 14 digits to the left of the decimal, the double is translated by PHP to scientific notation
// inserting a scientific notation string fails
} elseif ($pdoParamType == "PDO::PARAM_STR" && $m1 - $m2 > 14) {
if (!isAEConnected()) {
if ($r !== false) {
echo "PDO param type $pdoParamType should not be compatible with $typeFull when the number of integers is greater than 14\n";
}
} else {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
}
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) > $epsilon ||
abs($row['c_rand'] - $inputValues[1]) > $epsilon) {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
}
// check the case when inserting as PDO::PARAM_STR with input less than 14 digits to the left of the decimal
// and PDO::PARAM_BOOL, PDO::PARAM_INT or PDO::PARAM_LOB
// with or without AE: should work
} else {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
}
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) > $epsilon ||
abs($row['c_rand'] - $inputValues[1]) > $epsilon) {
// TODO: this is a workaround for the test to pass!!!!!
// with AE, doubles cannot be inserted into a decimal(38, 38) column
// remove the following if block to see the bug
// for more information see VSO task 2723
if (isAEConnected() && $m1 == 38 && $m2 == 38) {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
} else {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
} else {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
}
}
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing decimal(1, 0):
****Conversion from PDO::PARAM_BOOL to decimal(1, 0) is supported****
****Conversion from PDO::PARAM_INT to decimal(1, 0) is supported****
****Conversion from PDO::PARAM_STR to decimal(1, 0) is supported****
****Conversion from PDO::PARAM_LOB to decimal(1, 0) is supported****
Testing decimal(1, 1):
****Conversion from PDO::PARAM_BOOL to decimal(1, 1) is supported****
****Conversion from PDO::PARAM_INT to decimal(1, 1) is supported****
****Conversion from PDO::PARAM_STR to decimal(1, 1) is supported****
****Conversion from PDO::PARAM_LOB to decimal(1, 1) is supported****
Testing decimal(4, 0):
****Conversion from PDO::PARAM_BOOL to decimal(4, 0) is supported****
****Conversion from PDO::PARAM_INT to decimal(4, 0) is supported****
****Conversion from PDO::PARAM_STR to decimal(4, 0) is supported****
****Conversion from PDO::PARAM_LOB to decimal(4, 0) is supported****
Testing decimal(4, 1):
****Conversion from PDO::PARAM_BOOL to decimal(4, 1) is supported****
****Conversion from PDO::PARAM_INT to decimal(4, 1) is supported****
****Conversion from PDO::PARAM_STR to decimal(4, 1) is supported****
****Conversion from PDO::PARAM_LOB to decimal(4, 1) is supported****
Testing decimal(4, 4):
****Conversion from PDO::PARAM_BOOL to decimal(4, 4) is supported****
****Conversion from PDO::PARAM_INT to decimal(4, 4) is supported****
****Conversion from PDO::PARAM_STR to decimal(4, 4) is supported****
****Conversion from PDO::PARAM_LOB to decimal(4, 4) is supported****
Testing decimal(16, 0):
****Conversion from PDO::PARAM_BOOL to decimal(16, 0) is supported****
****Conversion from PDO::PARAM_INT to decimal(16, 0) is supported****
****Conversion from PDO::PARAM_LOB to decimal(16, 0) is supported****
Testing decimal(16, 1):
****Conversion from PDO::PARAM_BOOL to decimal(16, 1) is supported****
****Conversion from PDO::PARAM_INT to decimal(16, 1) is supported****
****Conversion from PDO::PARAM_LOB to decimal(16, 1) is supported****
Testing decimal(16, 4):
****Conversion from PDO::PARAM_BOOL to decimal(16, 4) is supported****
****Conversion from PDO::PARAM_INT to decimal(16, 4) is supported****
****Conversion from PDO::PARAM_STR to decimal(16, 4) is supported****
****Conversion from PDO::PARAM_LOB to decimal(16, 4) is supported****
Testing decimal(16, 16):
****Conversion from PDO::PARAM_BOOL to decimal(16, 16) is supported****
****Conversion from PDO::PARAM_INT to decimal(16, 16) is supported****
****Conversion from PDO::PARAM_STR to decimal(16, 16) is supported****
****Conversion from PDO::PARAM_LOB to decimal(16, 16) is supported****
Testing decimal(38, 0):
****Conversion from PDO::PARAM_BOOL to decimal(38, 0) is supported****
****Conversion from PDO::PARAM_INT to decimal(38, 0) is supported****
****Conversion from PDO::PARAM_LOB to decimal(38, 0) is supported****
Testing decimal(38, 1):
****Conversion from PDO::PARAM_BOOL to decimal(38, 1) is supported****
****Conversion from PDO::PARAM_INT to decimal(38, 1) is supported****
****Conversion from PDO::PARAM_LOB to decimal(38, 1) is supported****
Testing decimal(38, 4):
****Conversion from PDO::PARAM_BOOL to decimal(38, 4) is supported****
****Conversion from PDO::PARAM_INT to decimal(38, 4) is supported****
****Conversion from PDO::PARAM_LOB to decimal(38, 4) is supported****
Testing decimal(38, 16):
****Conversion from PDO::PARAM_BOOL to decimal(38, 16) is supported****
****Conversion from PDO::PARAM_INT to decimal(38, 16) is supported****
****Conversion from PDO::PARAM_LOB to decimal(38, 16) is supported****
Testing decimal(38, 38):
****Conversion from PDO::PARAM_BOOL to decimal(38, 38) is supported****
****Conversion from PDO::PARAM_INT to decimal(38, 38) is supported****
****Conversion from PDO::PARAM_STR to decimal(38, 38) is supported****
****Conversion from PDO::PARAM_LOB to decimal(38, 38) is supported****
Testing numeric(1, 0):
****Conversion from PDO::PARAM_BOOL to numeric(1, 0) is supported****
****Conversion from PDO::PARAM_INT to numeric(1, 0) is supported****
****Conversion from PDO::PARAM_STR to numeric(1, 0) is supported****
****Conversion from PDO::PARAM_LOB to numeric(1, 0) is supported****
Testing numeric(1, 1):
****Conversion from PDO::PARAM_BOOL to numeric(1, 1) is supported****
****Conversion from PDO::PARAM_INT to numeric(1, 1) is supported****
****Conversion from PDO::PARAM_STR to numeric(1, 1) is supported****
****Conversion from PDO::PARAM_LOB to numeric(1, 1) is supported****
Testing numeric(4, 0):
****Conversion from PDO::PARAM_BOOL to numeric(4, 0) is supported****
****Conversion from PDO::PARAM_INT to numeric(4, 0) is supported****
****Conversion from PDO::PARAM_STR to numeric(4, 0) is supported****
****Conversion from PDO::PARAM_LOB to numeric(4, 0) is supported****
Testing numeric(4, 1):
****Conversion from PDO::PARAM_BOOL to numeric(4, 1) is supported****
****Conversion from PDO::PARAM_INT to numeric(4, 1) is supported****
****Conversion from PDO::PARAM_STR to numeric(4, 1) is supported****
****Conversion from PDO::PARAM_LOB to numeric(4, 1) is supported****
Testing numeric(4, 4):
****Conversion from PDO::PARAM_BOOL to numeric(4, 4) is supported****
****Conversion from PDO::PARAM_INT to numeric(4, 4) is supported****
****Conversion from PDO::PARAM_STR to numeric(4, 4) is supported****
****Conversion from PDO::PARAM_LOB to numeric(4, 4) is supported****
Testing numeric(16, 0):
****Conversion from PDO::PARAM_BOOL to numeric(16, 0) is supported****
****Conversion from PDO::PARAM_INT to numeric(16, 0) is supported****
****Conversion from PDO::PARAM_LOB to numeric(16, 0) is supported****
Testing numeric(16, 1):
****Conversion from PDO::PARAM_BOOL to numeric(16, 1) is supported****
****Conversion from PDO::PARAM_INT to numeric(16, 1) is supported****
****Conversion from PDO::PARAM_LOB to numeric(16, 1) is supported****
Testing numeric(16, 4):
****Conversion from PDO::PARAM_BOOL to numeric(16, 4) is supported****
****Conversion from PDO::PARAM_INT to numeric(16, 4) is supported****
****Conversion from PDO::PARAM_STR to numeric(16, 4) is supported****
****Conversion from PDO::PARAM_LOB to numeric(16, 4) is supported****
Testing numeric(16, 16):
****Conversion from PDO::PARAM_BOOL to numeric(16, 16) is supported****
****Conversion from PDO::PARAM_INT to numeric(16, 16) is supported****
****Conversion from PDO::PARAM_STR to numeric(16, 16) is supported****
****Conversion from PDO::PARAM_LOB to numeric(16, 16) is supported****
Testing numeric(38, 0):
****Conversion from PDO::PARAM_BOOL to numeric(38, 0) is supported****
****Conversion from PDO::PARAM_INT to numeric(38, 0) is supported****
****Conversion from PDO::PARAM_LOB to numeric(38, 0) is supported****
Testing numeric(38, 1):
****Conversion from PDO::PARAM_BOOL to numeric(38, 1) is supported****
****Conversion from PDO::PARAM_INT to numeric(38, 1) is supported****
****Conversion from PDO::PARAM_LOB to numeric(38, 1) is supported****
Testing numeric(38, 4):
****Conversion from PDO::PARAM_BOOL to numeric(38, 4) is supported****
****Conversion from PDO::PARAM_INT to numeric(38, 4) is supported****
****Conversion from PDO::PARAM_LOB to numeric(38, 4) is supported****
Testing numeric(38, 16):
****Conversion from PDO::PARAM_BOOL to numeric(38, 16) is supported****
****Conversion from PDO::PARAM_INT to numeric(38, 16) is supported****
****Conversion from PDO::PARAM_LOB to numeric(38, 16) is supported****
Testing numeric(38, 38):
****Conversion from PDO::PARAM_BOOL to numeric(38, 38) is supported****
****Conversion from PDO::PARAM_INT to numeric(38, 38) is supported****
****Conversion from PDO::PARAM_STR to numeric(38, 38) is supported****
****Conversion from PDO::PARAM_LOB to numeric(38, 38) is supported****

View file

@ -0,0 +1,113 @@
--TEST--
Test for inserting encrypted data into float types columns
--DESCRIPTION--
Test conversions between different float types
With or without Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a float column
2. From input of PDO::PARAM_INT to a float column
3. From input of PDO::PARAM_STR to a float column
4. From input of PDO::PARAM_LOB to a float column
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataType = "float";
$bits = array(1, 12, 24, 36, 53);
$inputValues = array(9223372036854775808.9223372036854775808, -9223372036854775808.9223372036854775808);
$numint = 19;
try {
$conn = connect();
foreach ($bits as $m) {
// compute the epsilon for comparing doubles
// when $m <= 24, the precision is 7 digits
// when $m > 24, the precision is 15 digits, but PHP float only supports up to 14 digits
$epsilon;
if ($m <= 24) {
$epsilon = pow(10, $numint - 7);
} else {
$epsilon = pow(10, $numint - 14);
}
$typeFull = "$dataType($m)";
echo "\nTesting $typeFull:\n";
//create table containing float(m) columns
$tbname = "test_" . $dataType . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c_det"), new ColumnMeta($typeFull, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
$r;
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c_det']) || !is_null($row['c_rand'])) {
echo "Conversion from $pdoParamType to $typeFull should insert NULL\n";
}
}
// check the case when inserting as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) < $epsilon && abs($row['c_rand'] - $inputValues[1]) < $epsilon) {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
} else {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
}
// cleanup
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing float(1):
****Conversion from PDO::PARAM_BOOL to float(1) is supported****
****Conversion from PDO::PARAM_INT to float(1) is supported****
****Conversion from PDO::PARAM_STR to float(1) is supported****
****Conversion from PDO::PARAM_LOB to float(1) is supported****
Testing float(12):
****Conversion from PDO::PARAM_BOOL to float(12) is supported****
****Conversion from PDO::PARAM_INT to float(12) is supported****
****Conversion from PDO::PARAM_STR to float(12) is supported****
****Conversion from PDO::PARAM_LOB to float(12) is supported****
Testing float(24):
****Conversion from PDO::PARAM_BOOL to float(24) is supported****
****Conversion from PDO::PARAM_INT to float(24) is supported****
****Conversion from PDO::PARAM_STR to float(24) is supported****
****Conversion from PDO::PARAM_LOB to float(24) is supported****
Testing float(36):
****Conversion from PDO::PARAM_BOOL to float(36) is supported****
****Conversion from PDO::PARAM_INT to float(36) is supported****
****Conversion from PDO::PARAM_STR to float(36) is supported****
****Conversion from PDO::PARAM_LOB to float(36) is supported****
Testing float(53):
****Conversion from PDO::PARAM_BOOL to float(53) is supported****
****Conversion from PDO::PARAM_INT to float(53) is supported****
****Conversion from PDO::PARAM_STR to float(53) is supported****
****Conversion from PDO::PARAM_LOB to float(53) is supported****

View file

@ -0,0 +1,169 @@
--TEST--
Test for inserting encrypted data into nchar types columns with different sizes
--DESCRIPTION--
Test conversions between different nchar types of different sizes
With or without Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a any nchar column
2. From input of PDO::PARAM_INT to a any nchar column
3. From input of PDO::PARAM_STR to a any nchar column
4. From input of PDO::PARAM_LOB to a any nchar column
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("nchar", "nvarchar", "nvarchar(max)");
$lengths = array(1, 8, 64, 512, 4000);
try {
$conn = connect();
foreach ($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
//create table containing nchar(m) or nvarchar(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new ColumnMeta($typeFull, "c1"));
createTable($conn, $tbname, $colMetaArr);
$input = str_repeat("d", $m);
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
$r;
$stmt = insertRow($conn, $tbname, array( "c1" => new BindParamOp(1, $input, $pdoParamType)), "prepareBindParam", $r);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $typeFull should be supported\n";
} else {
$sql = "SELECT c1 FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c1'])) {
echo "Conversion from $pdoParamType to $typeFull should insert NULL\n";
}
}
// check the case when inserting as PDO::PARAM_BOOL, PDO::PARAM_INT, PDO::PARAM_STR or PDO{{PARAM_LOB
// with or without AE: should work
} else {
$sql = "SELECT c1 FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (strlen($row['c1']) == $m) {
echo "****Conversion from $pdoParamType to $typeFull is supported****\n";
} else {
echo "Conversion from $pdoParamType to $typeFull causes data corruption\n";
}
}
// cleanup
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing nchar(1):
****Conversion from PDO::PARAM_BOOL to nchar(1) is supported****
****Conversion from PDO::PARAM_INT to nchar(1) is supported****
****Conversion from PDO::PARAM_STR to nchar(1) is supported****
****Conversion from PDO::PARAM_LOB to nchar(1) is supported****
Testing nchar(8):
****Conversion from PDO::PARAM_BOOL to nchar(8) is supported****
****Conversion from PDO::PARAM_INT to nchar(8) is supported****
****Conversion from PDO::PARAM_STR to nchar(8) is supported****
****Conversion from PDO::PARAM_LOB to nchar(8) is supported****
Testing nchar(64):
****Conversion from PDO::PARAM_BOOL to nchar(64) is supported****
****Conversion from PDO::PARAM_INT to nchar(64) is supported****
****Conversion from PDO::PARAM_STR to nchar(64) is supported****
****Conversion from PDO::PARAM_LOB to nchar(64) is supported****
Testing nchar(512):
****Conversion from PDO::PARAM_BOOL to nchar(512) is supported****
****Conversion from PDO::PARAM_INT to nchar(512) is supported****
****Conversion from PDO::PARAM_STR to nchar(512) is supported****
****Conversion from PDO::PARAM_LOB to nchar(512) is supported****
Testing nchar(4000):
****Conversion from PDO::PARAM_BOOL to nchar(4000) is supported****
****Conversion from PDO::PARAM_INT to nchar(4000) is supported****
****Conversion from PDO::PARAM_STR to nchar(4000) is supported****
****Conversion from PDO::PARAM_LOB to nchar(4000) is supported****
Testing nvarchar(1):
****Conversion from PDO::PARAM_BOOL to nvarchar(1) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(1) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(1) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(1) is supported****
Testing nvarchar(8):
****Conversion from PDO::PARAM_BOOL to nvarchar(8) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(8) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(8) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(8) is supported****
Testing nvarchar(64):
****Conversion from PDO::PARAM_BOOL to nvarchar(64) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(64) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(64) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(64) is supported****
Testing nvarchar(512):
****Conversion from PDO::PARAM_BOOL to nvarchar(512) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(512) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(512) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(512) is supported****
Testing nvarchar(4000):
****Conversion from PDO::PARAM_BOOL to nvarchar(4000) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(4000) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(4000) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(4000) is supported****
Testing nvarchar(max):
****Conversion from PDO::PARAM_BOOL to nvarchar(max) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(max) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(max) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from PDO::PARAM_BOOL to nvarchar(max) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(max) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(max) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from PDO::PARAM_BOOL to nvarchar(max) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(max) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(max) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from PDO::PARAM_BOOL to nvarchar(max) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(max) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(max) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from PDO::PARAM_BOOL to nvarchar(max) is supported****
****Conversion from PDO::PARAM_INT to nvarchar(max) is supported****
****Conversion from PDO::PARAM_STR to nvarchar(max) is supported****
****Conversion from PDO::PARAM_LOB to nvarchar(max) is supported****

View file

@ -1,39 +1,123 @@
--TEST--
Test for inserting and retrieving encrypted data of numeric types
Test for inserting encrypted data into numeric types columns
--DESCRIPTION--
Use PDOstatement::bindParam with all PDO::PARAM_ types
Test conversions between different numeric types
With Always Encrypted, implicit conversion works if:
1. From input of PDO::PARAM_BOOL to a real column
2. From input of PDO::PARAM_INT to a any numeric column
3. From input of PDO::PARAM_STR to a any numeric column
4. From input of PDO::PARAM_LOB to a any numeric column
Without Always Encrypted, all of the above works except for input of PDO::PARAM_STR to a bigint column in a x86 platform
PDO::PARAM_STR does not work for bigint in a x86 because in a x86 platform, the maximum value of an int is about 2147483647
Whereas in a x64 platform, the maximum value is about 9E18
In a x86 platform, when in integer is initialized to be > 2147483647, PHP implicitly change it to a float, represented by scientific notation
When inserting a scientific notation form numeric string, SQL Server returns a converting data type nvarchar to bigint error
Works for with AE because the sqltype used for binding parameter is determined by SQLDescribeParam,
unlike without AE, the sqltype is predicted to be nvarchar when the input is a string and the encoding is utf8
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array( "bit", "tinyint", "smallint", "int", "decimal(18,5)", "numeric(10,5)", "float", "real" );
$dataTypes = array("bit", "tinyint", "smallint", "int", "bigint", "real");
$epsilon = 1;
try {
$conn = connect();
$conn = connect("", array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
// create table
$tbname = getTableName();
// create table containing bit, tinyint, smallint, int, bigint, or real columns
$tbname = "test_" . $dataType;
$colMetaArr = array(new ColumnMeta($dataType, "c_det"), new ColumnMeta($dataType, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
// test each PDO::PARAM_ type
// insert by specifying PDO::PARAM_ types
foreach ($pdoParamTypes as $pdoParamType) {
// insert a row
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
$r;
if ($dataType == "decimal(18,5)") {
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, (string)$inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, (string)$inputValues[1], $pdoParamType)), "prepareBindParam", $r);
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
// check the case when inserting as PDO::PARAM_NULL
// with or without AE: NULL is inserted
if ($pdoParamType == "PDO::PARAM_NULL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if (!is_null($row['c_det']) || !is_null($row['c_rand'])) {
echo "Conversion from $pdoParamType to $dataType should insert NULL\n";
}
}
// check the case when inserting as PDO::PARAM_BOOL
// with or without AE: 1 or 0 should be inserted when inserting into an integer column
// double is inserted when inserting into a real column
} else if ($pdoParamType == "PDO::PARAM_BOOL") {
if ($r === false) {
echo "Conversion from $pdoParamType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($dataType == "real") {
if (abs($row['c_det'] - $inputValues[0]) < $epsilon && abs($row['c_rand'] - $inputValues[1]) < $epsilon) {
echo "****Conversion from $pdoParamType to $dataType is supported****\n";
} else {
echo "Conversion from $pdoParamType to $dataType causes data corruption\n";
}
} else {
if ($row['c_det'] != ($inputValues[0] != 0) && $row['c_rand'] != ($inputValues[1] != 0)) {
echo "Conversion from $pdoParamType to $dataType insert a boolean\n";
}
}
}
// check the case when inserting as PDO::PARAM_STR into a bigint column
// with AE: should work
// without AE: should not work on a x86 platform
} else if ($dataType == "bigint" && $pdoParamType == "PDO::PARAM_STR") {
if (!isAEConnected() && PHP_INT_SIZE == 4) {
if ($r !== false) {
echo "Conversion from $pdoParamType to $dataType should not be supported\n";
}
} else {
if ($r === false) {
echo "Conversion from $pdoParamType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($row['c_det'] != $inputValues[0] && $row['c_rand'] != $inputValues[1]) {
echo "Conversion from $pdoParamType to $dataType causes data corruption\n";
}
}
}
// check the case when inserting as PDO::PARAM_INT, PDO::PARAM_STR or PDO::PARAM_LOB
// with or without AE: should work
} else {
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType), "c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
}
if ($r === false) {
isIncompatibleTypesError($stmt, $dataType, $pdoParamType);
} else {
echo "****PDO param type $pdoParamType is compatible with encrypted $dataType****\n";
fetchAll($conn, $tbname);
if ($r === false) {
echo "Conversion from $pdoParamType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = $conn->query($sql);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if ($dataType == "real") {
if (abs($row['c_det'] - $inputValues[0]) < $epsilon && abs($row['c_rand'] - $inputValues[1]) < $epsilon) {
echo "****Conversion from $pdoParamType to $dataType is supported****\n";
} else {
echo "Conversion from $pdoParamType to $dataType causes data corruption\n";
}
} else {
if ($row['c_det'] == $inputValues[0] && $row['c_rand'] == $inputValues[1]) {
echo "****Conversion from $pdoParamType to $dataType is supported****\n";
} else {
echo "Conversion from $pdoParamType to $dataType causes data corruption\n";
}
}
}
}
$conn->query("TRUNCATE TABLE $tbname");
}
@ -46,139 +130,32 @@ try {
}
?>
--EXPECT--
Testing bit:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted bit****
c_det: 1
c_rand: 0
****PDO param type PDO::PARAM_NULL is compatible with encrypted bit****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted bit****
c_det: 1
c_rand: 0
****PDO param type PDO::PARAM_STR is compatible with encrypted bit****
c_det: 1
c_rand: 0
****PDO param type PDO::PARAM_LOB is compatible with encrypted bit****
c_det: 1
c_rand: 0
****Conversion from PDO::PARAM_INT to bit is supported****
****Conversion from PDO::PARAM_STR to bit is supported****
****Conversion from PDO::PARAM_LOB to bit is supported****
Testing tinyint:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted tinyint****
c_det: 0
c_rand: 1
****PDO param type PDO::PARAM_NULL is compatible with encrypted tinyint****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted tinyint****
c_det: 0
c_rand: 255
****PDO param type PDO::PARAM_STR is compatible with encrypted tinyint****
c_det: 0
c_rand: 255
****PDO param type PDO::PARAM_LOB is compatible with encrypted tinyint****
c_det: 0
c_rand: 255
****Conversion from PDO::PARAM_INT to tinyint is supported****
****Conversion from PDO::PARAM_STR to tinyint is supported****
****Conversion from PDO::PARAM_LOB to tinyint is supported****
Testing smallint:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted smallint****
c_det: 1
c_rand: 1
****PDO param type PDO::PARAM_NULL is compatible with encrypted smallint****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted smallint****
c_det: -32767
c_rand: 32767
****PDO param type PDO::PARAM_STR is compatible with encrypted smallint****
c_det: -32767
c_rand: 32767
****PDO param type PDO::PARAM_LOB is compatible with encrypted smallint****
c_det: -32767
c_rand: 32767
****Conversion from PDO::PARAM_INT to smallint is supported****
****Conversion from PDO::PARAM_STR to smallint is supported****
****Conversion from PDO::PARAM_LOB to smallint is supported****
Testing int:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted int****
c_det: 1
c_rand: 1
****PDO param type PDO::PARAM_NULL is compatible with encrypted int****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted int****
c_det: -2147483647
c_rand: 2147483647
****PDO param type PDO::PARAM_STR is compatible with encrypted int****
c_det: -2147483647
c_rand: 2147483647
****PDO param type PDO::PARAM_LOB is compatible with encrypted int****
c_det: -2147483647
c_rand: 2147483647
****Conversion from PDO::PARAM_INT to int is supported****
****Conversion from PDO::PARAM_STR to int is supported****
****Conversion from PDO::PARAM_LOB to int is supported****
Testing decimal(18,5):
****PDO param type PDO::PARAM_BOOL is compatible with encrypted decimal(18,5)****
c_det: -9223372036854.80000
c_rand: 9223372036854.80000
****PDO param type PDO::PARAM_NULL is compatible with encrypted decimal(18,5)****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted decimal(18,5)****
c_det: -9223372036854.80000
c_rand: 9223372036854.80000
****PDO param type PDO::PARAM_STR is compatible with encrypted decimal(18,5)****
c_det: -9223372036854.80000
c_rand: 9223372036854.80000
****PDO param type PDO::PARAM_LOB is compatible with encrypted decimal(18,5)****
c_det: -9223372036854.80000
c_rand: 9223372036854.80000
Testing numeric(10,5):
****PDO param type PDO::PARAM_BOOL is compatible with encrypted numeric(10,5)****
c_det: -21474.83647
c_rand: 21474.83647
****PDO param type PDO::PARAM_NULL is compatible with encrypted numeric(10,5)****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted numeric(10,5)****
c_det: -21474.83647
c_rand: 21474.83647
****PDO param type PDO::PARAM_STR is compatible with encrypted numeric(10,5)****
c_det: -21474.83647
c_rand: 21474.83647
****PDO param type PDO::PARAM_LOB is compatible with encrypted numeric(10,5)****
c_det: -21474.83647
c_rand: 21474.83647
Testing float:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted float****
c_det: -9223372036.8547993
c_rand: 9223372036.8547993
****PDO param type PDO::PARAM_NULL is compatible with encrypted float****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted float****
c_det: -9223372036.8547993
c_rand: 9223372036.8547993
****PDO param type PDO::PARAM_STR is compatible with encrypted float****
c_det: -9223372036.8547993
c_rand: 9223372036.8547993
****PDO param type PDO::PARAM_LOB is compatible with encrypted float****
c_det: -9223372036.8547993
c_rand: 9223372036.8547993
Testing bigint:
****Conversion from PDO::PARAM_INT to bigint is supported****
****Conversion from PDO::PARAM_LOB to bigint is supported****
Testing real:
****PDO param type PDO::PARAM_BOOL is compatible with encrypted real****
c_det: -2147.4829
c_rand: 2147.4829
****PDO param type PDO::PARAM_NULL is compatible with encrypted real****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted real****
c_det: -2147.4829
c_rand: 2147.4829
****PDO param type PDO::PARAM_STR is compatible with encrypted real****
c_det: -2147.4829
c_rand: 2147.4829
****PDO param type PDO::PARAM_LOB is compatible with encrypted real****
c_det: -2147.4829
c_rand: 2147.4829
****Conversion from PDO::PARAM_BOOL to real is supported****
****Conversion from PDO::PARAM_INT to real is supported****
****Conversion from PDO::PARAM_STR to real is supported****
****Conversion from PDO::PARAM_LOB to real is supported****

View file

@ -1,112 +0,0 @@
--TEST--
Test for inserting and retrieving encrypted data of string types
--DESCRIPTION--
Use PDOstatement::bindParam with all PDO::PARAM_ types
--SKIPIF--
<?php require('skipif_mid-refactor.inc'); ?>
--FILE--
<?php
require_once("MsCommon_mid-refactor.inc");
require_once("AEData.inc");
$dataTypes = array("char(5)", "varchar(max)", "nchar(5)", "nvarchar(max)");
try {
$conn = connect('', array(), PDO::ERRMODE_SILENT);
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
// create table
$tbname = getTableName();
$colMetaArr = array(new ColumnMeta($dataType, "c_det"), new ColumnMeta($dataType, "c_rand", null, "randomized"));
createTable($conn, $tbname, $colMetaArr);
// prepare statement for inserting into table
foreach ($pdoParamTypes as $pdoParamType) {
// insert a row
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
$r;
$stmt = insertRow($conn, $tbname, array( "c_det" => new BindParamOp(1, $inputValues[0], $pdoParamType),"c_rand" => new BindParamOp(2, $inputValues[1], $pdoParamType)), "prepareBindParam", $r);
if ($r === false) {
isIncompatibleTypesError($stmt, $dataType, $pdoParamType);
} else {
echo "****PDO param type $pdoParamType is compatible with encrypted $dataType****\n";
fetchAll($conn, $tbname);
}
$conn->query("TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
unset($stmt);
unset($conn);
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
--EXPECT--
Testing char(5):
****PDO param type PDO::PARAM_BOOL is compatible with encrypted char(5)****
c_det: -leng
c_rand: th, n
****PDO param type PDO::PARAM_NULL is compatible with encrypted char(5)****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted char(5)****
c_det: -leng
c_rand: th, n
****PDO param type PDO::PARAM_STR is compatible with encrypted char(5)****
c_det: -leng
c_rand: th, n
****PDO param type PDO::PARAM_LOB is compatible with encrypted char(5)****
c_det: -leng
c_rand: th, n
Testing varchar(max):
****PDO param type PDO::PARAM_BOOL is compatible with encrypted varchar(max)****
c_det: Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.
c_rand: Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.
****PDO param type PDO::PARAM_NULL is compatible with encrypted varchar(max)****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted varchar(max)****
c_det: Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.
c_rand: Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.
****PDO param type PDO::PARAM_STR is compatible with encrypted varchar(max)****
c_det: Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.
c_rand: Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.
****PDO param type PDO::PARAM_LOB is compatible with encrypted varchar(max)****
c_det: Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.
c_rand: Each non-null varchar(max) or nvarchar(max) column requires 24 bytes of additional fixed allocation which counts against the 8,060 byte row limit during a sort operation.
Testing nchar(5):
****PDO param type PDO::PARAM_BOOL is compatible with encrypted nchar(5)****
c_det: -leng
c_rand: th Un
****PDO param type PDO::PARAM_NULL is compatible with encrypted nchar(5)****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted nchar(5)****
c_det: -leng
c_rand: th Un
****PDO param type PDO::PARAM_STR is compatible with encrypted nchar(5)****
c_det: -leng
c_rand: th Un
****PDO param type PDO::PARAM_LOB is compatible with encrypted nchar(5)****
c_det: -leng
c_rand: th Un
Testing nvarchar(max):
****PDO param type PDO::PARAM_BOOL is compatible with encrypted nvarchar(max)****
c_det: When prefixing a string constant with the letter N, the implicit conversion will result in a Unicode string if the constant to convert does not exceed the max length for a Unicode string data type (4,000).
c_rand: Otherwise, the implicit conversion will result in a Unicode large-value (max).
****PDO param type PDO::PARAM_NULL is compatible with encrypted nvarchar(max)****
c_det:
c_rand:
****PDO param type PDO::PARAM_INT is compatible with encrypted nvarchar(max)****
c_det: When prefixing a string constant with the letter N, the implicit conversion will result in a Unicode string if the constant to convert does not exceed the max length for a Unicode string data type (4,000).
c_rand: Otherwise, the implicit conversion will result in a Unicode large-value (max).
****PDO param type PDO::PARAM_STR is compatible with encrypted nvarchar(max)****
c_det: When prefixing a string constant with the letter N, the implicit conversion will result in a Unicode string if the constant to convert does not exceed the max length for a Unicode string data type (4,000).
c_rand: Otherwise, the implicit conversion will result in a Unicode large-value (max).
****PDO param type PDO::PARAM_LOB is compatible with encrypted nvarchar(max)****
c_det: When prefixing a string constant with the letter N, the implicit conversion will result in a Unicode string if the constant to convert does not exceed the max length for a Unicode string data type (4,000).
c_rand: Otherwise, the implicit conversion will result in a Unicode large-value (max).

View file

@ -157,13 +157,16 @@ class BindParamOption
$type_size = explode("(", $this->sqlType);
$type = $type_size[0];
if (count($type_size) > 1) {
$size = $type_size[1];
$size = rtrim($type_size[1], ")");
$prec_scal = explode(",", $size);
if (count($prec_scal) > 1) {
$prec = $prec_scal[0];
$scal = rtrim($prec_scal[1], ")");
$scal = $prec_scal[1];
$size = null;
}
if (strpos($size, "max") !== false) {
$size = trim($size, "'");
}
}
// get the sqlType constant
try {

View file

@ -0,0 +1,271 @@
--TEST--
Test for inserting encrypted data into binary types columns with different sizes
--DESCRIPTION--
Test implicit conversions between different binary types of different sizes
With Always Encrypted, implicit conversion works if:
1. From input of SQLSRV_SQLTYPE_BINARY(n) to a larger binary(m) column where n <= m
2. From input of SQLSRV_SQLTYPE_BINARY(n) to a larger varbinary(m) column where n <= m (m can be max)
3. From input of SQLSRV_SQLTYPE_VARBINARY(n) to a larger binary(m) column where n <= m
4. From input of SQLSRV_SQLTYPE_VARBINARY(n) to a larger varbinary(m) column where n <= m (m can be max)
Without AlwaysEncrypted, implicit conversion between different binary types and sizes works
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$dataTypes = array("binary", "varbinary", "varbinary(max)");
$lengths = array(1, 8, 64, 512, 4000);
$sqlTypes = array("SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_VARBINARY('max')");
$sqltypeLengths = $lengths;
$inputValues = array("d", "f");
$conn = AE\connect();
foreach($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach ($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
// create table containing binary(m) or varbinary(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new AE\ColumnMeta($typeFull, "c_det"), new AE\ColumnMeta($typeFull, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying SQLSRV_SQLTYPE_BINARY(n) or SQLSRV_SQLTYPE_VARBINARY(n)
// with AE, should be successful as long as the SQLSRV_SQLTYPE length (n) is smaller than the column length (m)
foreach($sqlTypes as $sqlType) {
$maxsqltype = strpos($sqlType, "max");
foreach($sqltypeLengths as $n) {
if ($maxsqltype !== false) {
$sqltypeFull = $sqlType;
} else {
$sqltypeFull = "$sqlType($n)";
}
//insert a row
$inputs = array(new AE\BindParamOption($inputValues[0], null, "SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY)", $sqltypeFull),
new AE\BindParamOption($inputValues[1], null, "SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY)", $sqltypeFull));
$r;
$stmt = AE\insertRow($conn, $tbname, array("c_det" => $inputs[0], "c_rand" => $inputs[1]), $r, AE\INSERT_PREPARE_PARAMS);
// check the case when SQLSRV_SQLTYPE length (n) is greater than the column length (m)
// with AE: should not work
// without AE: should work
if (($n > $m || $maxsqltype) && !$maxcol) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqltypeFull to $typeFull should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqltypeFull to $typeFull expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
}
}
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
}
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (trim($row['c_det']) != $inputValues[0] || trim($row['c_rand']) != $inputValues[1]) {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
// check the case when SQLSRV_SQLTYPE length (n) is less than or equal to the column length (m)
// should work with AE or non AE
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (trim($row['c_det']) == $inputValues[0] || trim($row['c_rand']) == $inputValues[1]) {
echo "****Conversion from $sqltypeFull to $typeFull is supported****\n";
} else {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
sqlsrv_query($conn, "TRUNCATE TABLE $tbname");
}
}
dropTable($conn, $tbname);
}
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing binary(1):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to binary(1) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to binary(1) is supported****
Testing binary(8):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to binary(8) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to binary(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to binary(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to binary(8) is supported****
Testing binary(64):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to binary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to binary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to binary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to binary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to binary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to binary(64) is supported****
Testing binary(512):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to binary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to binary(512) is supported****
Testing binary(4000):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to binary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to binary(4000) is supported****
Testing varbinary(1):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(1) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(1) is supported****
Testing varbinary(8):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(8) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(8) is supported****
Testing varbinary(64):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(64) is supported****
Testing varbinary(512):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(512) is supported****
Testing varbinary(4000):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to varbinary(4000) is supported****
Testing varbinary(max):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
Testing varbinary(max):
****Conversion from SQLSRV_SQLTYPE_BINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_BINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(1) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(8) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(64) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(512) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY(4000) to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARBINARY('max') to varbinary(max) is supported****

View file

@ -0,0 +1,333 @@
--TEST--
Test for inserting encrypted data of char types with different sizes
--DESCRIPTION--
Test implicit conversions between different char types of different sizes
With Always Encrypted, implicit conversion works if:
1. From input of SQLSRV_SQLTYPE_CHAR(n) to a larger char(m) column where n <= m
2. From input of SQLSRV_SQLTYPE_CHAR(n) to a larger varchar(m) column where n <= m (m can be max)
3. From input of SQLSRV_SQLTYPE_VARCHAR(n) to a larger char(m) column where n <= m
4. From input of SQLSRV_SQLTYPE_VARCHAR(n) to a larger varchar(m) column where n <= m (m can be max)
Without AlwaysEncrypted, implicit conversion between different binary types and sizes works
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$dataTypes = array("char", "varchar", "varchar(max)");
$lengths = array(1, 8, 64, 512, 4096, 8000);
$sqlTypes = array("SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_VARCHAR('max')");
$sqltypeLengths = $lengths;
$inputValue = "d";
$conn = AE\connect();
foreach($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
// create table containing char(m) or varchar(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new AE\ColumnMeta($typeFull, "c1"));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying SQLSRV_SQLTYPE_CHAR(n) or SQLSRV_SQLTYPE_VARCHAR(n)
// with AE, should be successful as long as the SQLSRV_SQLTYPE length (n) is smaller than the column length (m)
foreach($sqlTypes as $sqlType) {
$maxsqltype = strpos($sqlType, "max");
foreach($sqltypeLengths as $n) {
if ($maxsqltype !== false) {
$sqltypeFull = $sqlType;
} else {
$sqltypeFull = "$sqlType($n)";
}
//insert a row
$input = new AE\BindParamOption($inputValue, null, null, $sqltypeFull);
$r;
$stmt = AE\insertRow($conn, $tbname, array("c1" => $input), $r, AE\INSERT_PREPARE_PARAMS);
// check the case when SQLSRV_SQLTYPE length (n) is greater than the column length (m)
// with AE: should not work
// without AE: should work
if (($n > $m || $maxsqltype) && !$maxcol) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqltypeFull to $typeFull should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqltypeFull to $typeFull expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
}
}
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
}
$sql = "SELECT c1 FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (trim($row['c1']) != $inputValue) {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
// check the case when SQLSRV_SQLTYPE length (n) is less than or equal to the column length (m)
// should work with AE or non AE
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
} else {
$sql = "SELECT c1 FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (trim($row['c1']) == $inputValue) {
echo "****Conversion from $sqltypeFull to $typeFull is supported****\n";
} else {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
sqlsrv_query($conn, "TRUNCATE TABLE $tbname");
}
}
dropTable($conn, $tbname);
}
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing char(1):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to char(1) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to char(1) is supported****
Testing char(8):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to char(8) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to char(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to char(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to char(8) is supported****
Testing char(64):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to char(64) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to char(64) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to char(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to char(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to char(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to char(64) is supported****
Testing char(512):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to char(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to char(512) is supported****
Testing char(4096):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to char(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to char(4096) is supported****
Testing char(8000):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to char(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to char(8000) is supported****
Testing varchar(1):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(1) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(1) is supported****
Testing varchar(8):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(8) is supported****
Testing varchar(64):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(64) is supported****
Testing varchar(512):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(512) is supported****
Testing varchar(4096):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(4096) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(4096) is supported****
Testing varchar(8000):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(8000) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(8000) is supported****
Testing varchar(max):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
Testing varchar(max):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
Testing varchar(max):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
Testing varchar(max):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
Testing varchar(max):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
Testing varchar(max):
****Conversion from SQLSRV_SQLTYPE_CHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_CHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(1) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(64) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(512) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(4096) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR(8000) to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_VARCHAR('max') to varchar(max) is supported****

View file

@ -0,0 +1,181 @@
--TEST--
Test for inserting encrypted data of datetime2, datetimeoffset and time datatypes with different precisions
--DESCRIPTION--
Test implicit conversions between different precisions
With Always Encrypted, implicit conversion works if:
1. From input of SQLSRV_SQLTYPE_DATETIME2 to a dateteim2(7) column
2. From input of SQLSRV_SQLTYPE_DATETIMEOFFSET to a datetimeoffset(7) column
3. From input of SQLSRV_SQLTYPE_TIME to a time(7) column
Note: with AE, implicit converion should work as long as the SQLSRV_SQLTYPE has a smaller precision than the one defined in the column. However, the SQLSRV driver does not let the user specify the precision in these SQLSRV_SQLTYPE_* constants and they are all default to a precision of 7. Hence when user specifies SQLSRV_SQLTYPE_DATETIME2, SQLSRV_SQLTYPE_DATETIMEOFFSET or SQLSRV_SQLTYPE_TIME when binding parameter during insertion, only insertion into a column of precision 7 is allowed.
Without AlwaysEncrypted, implicit conversion between different precisions works
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
function compareDate($dtobj, $dtstr, $dataType, $precision) {
$dtobj_date = $dtobj->format("Y-m-d H:i:s.u");
$dtobj_timezone = $dtobj->getTimezone()->getName();
$dtarr = null;
if ($dataType == "datetimeoffset") {
$dtarr = explode(' ', $dtstr);
}
// php only supports up to 6 decimal places in datetime
// drop the last decimal place before comparing
if ($precision == 7) {
$dtstr = substr($dtstr, 0, -1);
if (!is_null($dtarr)) {
$dtarr[1] = substr($dtarr[1], 0, -1);
}
}
if (strpos($dtobj_date, $dtstr) !== false) {
return true;
}
if ($dataType == "datetimeoffset") {
if (strpos($dtobj_date, $dtarr[0]) !== false && strpos($dtobj_date, $dtarr[1]) !== false && strpos($dtobj_timezone, $dtarr[2]) !== false) {
return true;
}
}
return false;
}
$dataTypes = array("datetime2", "datetimeoffset", "time");
$precisions = array(0, 1, 2, 4, 7);
$inputValuesInit = array("datetime2" => array("0001-01-01 00:00:00", "9999-12-31 23:59:59"),
"datetimeoffset" => array("0001-01-01 00:00:00 -14:00", "9999-12-31 23:59:59 +14:00"),
"time" => array("00:00:00", "23:59:59"));
$conn = AE\connect();
foreach($dataTypes as $dataType) {
foreach($precisions as $m) {
// add $m number of decimal digits to the some input values
$inputValues[0] = $inputValuesInit[$dataType][0];
$inputValues[1] = $inputValuesInit[$dataType][1];
if ($m != 0) {
if ($dataType == "datetime2") {
$inputValues[1] .= "." . str_repeat("4", $m);
} else if ($dataType == "datetimeoffset") {
$dtoffsetPieces = explode(" ", $inputValues[1]);
$inputValues[1] = $dtoffsetPieces[0] . " " . $dtoffsetPieces[1] . "." . str_repeat("4", $m) . " " . $dtoffsetPieces[2];
} else if ($dataType == "time") {
$inputValues[0] .= "." . str_repeat("0", $m);
$inputValues[1] .= "." . str_repeat("4", $m);
}
}
$typeFull = "$dataType($m)";
echo "\nTesting $typeFull:\n";
// create table containing datetime2(m), datetimeoffset(m) or time(m) columns
$tbname = "test_" . $dataType . $m;
$colMetaArr = array(new AE\ColumnMeta($typeFull, "c_det"), new AE\ColumnMeta($typeFull, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying the corresponding SQLSRV_SQLTYPE
$sqlType = "SQLSRV_SQLTYPE_" . strtoupper($dataType);
$inputs = array(new AE\BindParamOption($inputValues[0], null, null, $sqlType),
new AE\BindParamOption($inputValues[1], null, null, $sqlType));
$r;
$stmt = AE\insertRow($conn, $tbname, array("c_det" => $inputs[0], "c_rand" => $inputs[1]), $r, AE\INSERT_PREPARE_PARAMS);
// check the case when the column precision (m) is less than 7
// with AE: should not work
// with AE: should work
if ($m < 7) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqlType to $typeFull should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqlType to $typeFull expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
} else {
echo "Test successfully done\n";
}
}
} else {
if ($r === false) {
echo "Conversion from $sqlType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (!compareDate($row['c_det'], $inputValues[0], $dataType, $m) || !compareDate($row['c_rand'], $inputValues[1], $dataType, $m)) {
echo "Conversion from $sqlType to $typeFull causes data corruption\n";
} else {
echo "Test successfully done\n";
}
}
}
// check the case when the column precision is 7
// should work with AE or non AE
} else {
if ($r === false) {
echo "Conversion from $sqlType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (compareDate($row['c_det'], $inputValues[0], $dataType, $m) && compareDate($row['c_rand'], $inputValues[1], $dataType, $m)) {
echo "****Conversion from $sqlType to $typeFull is supported****\n";
} else {
echo "Conversion from $sqlType to $typeFull causes data corruption\n";
var_dump($row);
}
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
dropTable($conn, $tbname);
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing datetime2(0):
Test successfully done
Testing datetime2(1):
Test successfully done
Testing datetime2(2):
Test successfully done
Testing datetime2(4):
Test successfully done
Testing datetime2(7):
****Conversion from SQLSRV_SQLTYPE_DATETIME2 to datetime2(7) is supported****
Testing datetimeoffset(0):
Test successfully done
Testing datetimeoffset(1):
Test successfully done
Testing datetimeoffset(2):
Test successfully done
Testing datetimeoffset(4):
Test successfully done
Testing datetimeoffset(7):
****Conversion from SQLSRV_SQLTYPE_DATETIMEOFFSET to datetimeoffset(7) is supported****
Testing time(0):
Test successfully done
Testing time(1):
Test successfully done
Testing time(2):
Test successfully done
Testing time(4):
Test successfully done
Testing time(7):
****Conversion from SQLSRV_SQLTYPE_TIME to time(7) is supported****

View file

@ -0,0 +1,247 @@
--TEST--
Test for inserting encrypted data of decimal types with different precisions and scales
--DESCRIPTION--
Test implicit conversions between different precisions and scales
With Always Encrypted, no implicit conversion works for decimal datatypes, the precision and scale specified in the SQLSRV_SQLTYPE must be identical to the precision and scale defined in the column
Without AlwaysEncrypted, implicit conversion between precisions or scales works if:
1. From input of SQLSRV_SQLTYPE_DECIMAL(n1, n2) to a decimal(m1, m2) column where n1 - n2 > m1 - m2 and
2. where n2 != 0 && m1 != m2
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$dataTypes = array("decimal", "numeric");
$precisions = array(1 => array(0, 1),
4 => array(0, 1, 4),
16 => array(0, 1, 4, 16),
38 => array(0, 1, 4, 16, 38));
$sqlTypes = array("SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC");
$sqltypePrecisions = $precisions;
$inputValuesInit = array(92233720368547758089223372036854775808, -92233720368547758089223372036854775808);
$maxInPrecision = 38;
$conn = AE\connect();
foreach($dataTypes as $dataType) {
foreach($precisions as $m1 => $inScales) {
foreach($inScales as $m2) {
// change the number of integers in the input values to be $m1 - $m2
$precDiff = $maxInPrecision - ($m1 - $m2);
$inputValues = $inputValuesInit;
foreach ($inputValues as &$inputValue) {
$inputValue = $inputValue / pow(10, $precDiff);
}
$typeFull = "$dataType($m1, $m2)";
echo "\nTesting $typeFull:\n";
// create table containing decimal(m1, m2) or numeric(m1, m2) columns
$tbname = "test_" . $dataType . $m1 . $m2;
$colMetaArr = array(new AE\ColumnMeta($typeFull, "c_det"), new AE\ColumnMeta($typeFull, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying SQLSRV_SQLTYPE_DECIMAL(n1, n2) or SQLSRV_SQLTYPE_NUMERIC(n1, n2)
// with AE, should only be successful if the SQLSRV_SQLTYPE precision (n1) and scale (n2) are the same as the column precision (m1) and scale (m2)
foreach($sqlTypes as $sqlType) {
foreach($sqltypePrecisions as $n1 => $sqltypeScales) {
foreach($sqltypeScales as $n2) {
// compute the epsilon for comparing doubles
// float in PHP only has a precision of roughtly 14 digits: http://php.net/manual/en/language.types.float.php
// the smaller precision and scale (n1 and n2 vs m1 and m2) take precedence
$epsilon;
$smallerprec = min($m1, $n1);
$smallerscale = min($m2, $n2);
if ($smallerprec < 14) {
$epsilon = pow(10, $smallerscale * -1);
} else {
$numint = $smallerprec - $smallerscale;
if ($numint < 14) {
$epsilon = pow(10, (14 - $numint) * -1);
} else {
$epsilon = pow(10, $numint - 14);
}
}
$sqltypeFull = "$sqlType($n1, $n2)";
//insert a row
$inputs = array(new AE\BindParamOption((string)$inputValues[0], null, null, $sqltypeFull),
new AE\BindParamOption((string)$inputValues[1], null, null, $sqltypeFull));
$r;
$stmt = AE\insertRow($conn, $tbname, array("c_det" => $inputs[0], "c_rand" => $inputs[1]), $r, AE\INSERT_PREPARE_PARAMS);
// check the case when the SQLSRV_SQLTYPE precision (n1) is not the same as the column precision (m1)
// or the SQLSRV_SQLTYPE scale (n2) is not the same as the column precision (m2)
// with AE: should not work
// without AE: should not work if n1 - n2 < m1 - m2 (Numeric value out of range error)
// or n2 != 0 && $m1 == $m2 (Arithmetic overflow error)
if ($n1 != $m1 || $n2 != $m2) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqltypeFull to $typeFull should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqltypeFull to $typeFull expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
}
}
} else {
if ($n1 - $n2 < $m1 - $m2 || ($m1 == $m2 && $n2 == 0)) {
if ($r !== false) {
echo "Conversion from $sqltypeFull to $typeFull should not be supported\n";
}
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) > $epsilon || abs($row['c_rand'] - $inputValues[1]) > $epsilon) {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
}
}
// check the case when the SQLSRV_SQLTYPE precision (n1) and scale (n2) are the same as the column precision (m1) and scale (m2)
// should work with AE or non AE
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) < $epsilon && abs($row['c_rand'] - $inputValues[1]) < $epsilon) {
echo "****Conversion from $sqltypeFull to $typeFull is supported****\n";
} else {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
sqlsrv_query($conn, "TRUNCATE TABLE $tbname");
}
}
}
dropTable($conn, $tbname);
}
}
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing decimal(1, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(1, 0) to decimal(1, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(1, 0) to decimal(1, 0) is supported****
Testing decimal(1, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(1, 1) to decimal(1, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(1, 1) to decimal(1, 1) is supported****
Testing decimal(4, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(4, 0) to decimal(4, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(4, 0) to decimal(4, 0) is supported****
Testing decimal(4, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(4, 1) to decimal(4, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(4, 1) to decimal(4, 1) is supported****
Testing decimal(4, 4):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(4, 4) to decimal(4, 4) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(4, 4) to decimal(4, 4) is supported****
Testing decimal(16, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 0) to decimal(16, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 0) to decimal(16, 0) is supported****
Testing decimal(16, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 1) to decimal(16, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 1) to decimal(16, 1) is supported****
Testing decimal(16, 4):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 4) to decimal(16, 4) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 4) to decimal(16, 4) is supported****
Testing decimal(16, 16):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 16) to decimal(16, 16) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 16) to decimal(16, 16) is supported****
Testing decimal(38, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 0) to decimal(38, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 0) to decimal(38, 0) is supported****
Testing decimal(38, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 1) to decimal(38, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 1) to decimal(38, 1) is supported****
Testing decimal(38, 4):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 4) to decimal(38, 4) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 4) to decimal(38, 4) is supported****
Testing decimal(38, 16):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 16) to decimal(38, 16) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 16) to decimal(38, 16) is supported****
Testing decimal(38, 38):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 38) to decimal(38, 38) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 38) to decimal(38, 38) is supported****
Testing numeric(1, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(1, 0) to numeric(1, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(1, 0) to numeric(1, 0) is supported****
Testing numeric(1, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(1, 1) to numeric(1, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(1, 1) to numeric(1, 1) is supported****
Testing numeric(4, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(4, 0) to numeric(4, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(4, 0) to numeric(4, 0) is supported****
Testing numeric(4, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(4, 1) to numeric(4, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(4, 1) to numeric(4, 1) is supported****
Testing numeric(4, 4):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(4, 4) to numeric(4, 4) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(4, 4) to numeric(4, 4) is supported****
Testing numeric(16, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 0) to numeric(16, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 0) to numeric(16, 0) is supported****
Testing numeric(16, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 1) to numeric(16, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 1) to numeric(16, 1) is supported****
Testing numeric(16, 4):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 4) to numeric(16, 4) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 4) to numeric(16, 4) is supported****
Testing numeric(16, 16):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(16, 16) to numeric(16, 16) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(16, 16) to numeric(16, 16) is supported****
Testing numeric(38, 0):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 0) to numeric(38, 0) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 0) to numeric(38, 0) is supported****
Testing numeric(38, 1):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 1) to numeric(38, 1) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 1) to numeric(38, 1) is supported****
Testing numeric(38, 4):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 4) to numeric(38, 4) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 4) to numeric(38, 4) is supported****
Testing numeric(38, 16):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 16) to numeric(38, 16) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 16) to numeric(38, 16) is supported****
Testing numeric(38, 38):
****Conversion from SQLSRV_SQLTYPE_DECIMAL(38, 38) to numeric(38, 38) is supported****
****Conversion from SQLSRV_SQLTYPE_NUMERIC(38, 38) to numeric(38, 38) is supported****

View file

@ -0,0 +1,103 @@
--TEST--
Test for inserting encrypted data of float types with different number of bits
--DESCRIPTION--
Test implicit conversions between different number of bits
With Always Encrypted, implicit conversion works if:
1. From input of SQLSRV_SQLTYPE_FLOAT to a float(m) column where m > 24
Note: with AE, implicit conversion should work as long as the SQLSRV_SQLTYPE has a smaller number of bits than the one defined in the column. However, the SQLSRV driver does not let the user specify the number of bits in the SQLSRV_SQLTYPE_FLOAT constant and it is default to 53. Hence when user specifies SQLSRV_SQLTYPE_FLOAT when binding parameter during insertion, only insertion into a column of > 24 is allowed.
Without AlwaysEncrypted, inplicit conversion between different number of bits works.
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$dataType = "float";
$bits = array(1, 12, 24, 36, 53);
$sqlType = "SQLSRV_SQLTYPE_FLOAT";
$inputValues = array(9223372036854775808.9223372036854775808, -9223372036854775808.9223372036854775808);
$epsilon = 100000;
$conn = AE\connect();
foreach($bits as $m) {
$typeFull = "$dataType($m)";
echo "\nTesting $typeFull:\n";
// create table containing float(m) columns
$tbname = "test_" . $dataType . $m;
$colMetaArr = array(new AE\ColumnMeta($typeFull, "c_det"), new AE\ColumnMeta($typeFull, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying SQLSRV_SQLTYPE_FLOAT
$inputs = array(new AE\BindParamOption($inputValues[0], null, null, $sqlType),
new AE\BindParamOption($inputValues[1], null, null, $sqlType));
$r;
$stmt = AE\insertRow($conn, $tbname, array("c_det" => $inputs[0], "c_rand" => $inputs[1]), $r, AE\INSERT_PREPARE_PARAMS);
// check the case when the column number of bits is less than 25
// with AE: should not work
// with AE: should work
if ($m < 25) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqlType to $typeFull should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqlType to $typeFull expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
} else {
echo "Test successfully done\n";
}
}
} else {
if ($r === false) {
echo "Conversion from $sqlType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) > $epsilon || abs($row['c_rand'] - $inputValues[1]) > $epsilon) {
echo "Conversion from $sqlType to $typeFull causes data corruption\n";
} else {
echo "Test successfully done\n";
}
}
}
// check the case when the column number of bits 25 or more
// should work with AE or non AE
} else {
if ($r === false) {
echo "Conversion from $sqlType to $typeFull should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (abs($row['c_det'] - $inputValues[0]) < $epsilon && abs($row['c_rand'] - $inputValues[1]) < $epsilon) {
echo "****Conversion from $sqlType to $typeFull is supported****\n";
} else {
echo "Conversion from $sqlType to $typeFull causes data corruption\n";
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
dropTable($conn, $tbname);
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing float(1):
Test successfully done
Testing float(12):
Test successfully done
Testing float(24):
Test successfully done
Testing float(36):
****Conversion from SQLSRV_SQLTYPE_FLOAT to float(36) is supported****
Testing float(53):
****Conversion from SQLSRV_SQLTYPE_FLOAT to float(53) is supported****

View file

@ -0,0 +1,124 @@
--TEST--
Test for inserting encrypted data of int types
--DESCRIPTION--
Test implicit conversions between different integer types
With Always Encrypted, implicit conversion works if:
1. From input SQLSRV_SQLTYPE_BIT to a bit column
2. From input SQLSRV_SQLTYPE_BIT to a tinyint column
3. From input SQLSRV_SQLTYPE_BIT to a smallint column
4. From input SQLSRV_SQLTYPE_BIT to an int column
5. From input SQLSRV_SQLTYPE_BIT to a bigint column
6. From input SQLSRV_SQLTYPE_TINYINT to a tinyint column
7. From input SQLSRV_SQLTYPE_TINYINT to a smallint column
8. From input SQLSRV_SQLTYPE_TINYINT to an int column
9. From input SQLSRV_SQLTYPE_TINYINT to a bigint column
10. From input SQLSRV_SQLTYPE_SMALLINT to a smallint column
11. From input SQLSRV_SQLTYPE_SMALLINT to an int column
12. From input SQLSRV_SQLTYPE_SMALLINT to a bigint column
13. From input SQLSRV_SQLTYPE_INT to an int column
14. From input SQLSRV_SQLTYPE_INT to a bigint column
15. From input SQLSRV_SQLTYPE_BIGINT to a bigint column
Without AlwaysEncrypted, inplicit conversion between different integer types works
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$dataTypes = array("bit", "tinyint", "smallint", "int", "bigint");
$sqlTypes = array("SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_BIGINT");
$inputValues = array(1, 0);
// this is a list of implicit datatype conversion that AE supports
$aeConvList = array("bit" => array("SQLSRV_SQLTYPE_BIT"),
"tinyint" => array("SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TINYINT"),
"smallint" => array("SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_SMALLINT"),
"int" => array("SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_INT"),
"bigint" => array("SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_BIGINT"));
$conn = AE\connect();
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
// create table containing bit, tinyint, smallint, int, or bigint columns
$tbname = "test_" . $dataType;
$colMetaArr = array( new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying different SQLSRV_SQLTYPE integer constants
// with AE, should only be successful if the SQLSRV_SQLTYPE is smaller in size than the column datatype
foreach($sqlTypes as $sqlType) {
$inputs = array(new AE\BindParamOption($inputValues[0], null, null, $sqlType), new AE\BindParamOption($inputValues[1], null, null, $sqlType));
$r;
$stmt = AE\insertRow($conn, $tbname, array($colMetaArr[0]->colName => $inputs[0], $colMetaArr[1]->colName => $inputs[1]), $r, AE\INSERT_PREPARE_PARAMS);
// check the case if the type conversion is not listed in $aeConvList
if (!in_array($sqlType, $aeConvList["$dataType"])) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqlType to $dataType should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqlType to $dataType expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
}
}
} else {
if ($r === false) {
echo "Conversion from $sqlType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($row['c_det'] != $inputValues[0] || $row['c_rand'] != $inputValues[1]) {
echo "Conversion from $sqlType to $dataType causes data corruption\n";
}
}
}
} else {
if ($r === false) {
echo "Conversion from $sqlType to $dataType should be supported\n";
} else {
$sql = "SELECT c_det, c_rand FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($row['c_det'] == $inputValues[0] && $row['c_rand'] == $inputValues[1]) {
echo "****Conversion from $sqlType to $dataType is supported****\n";
} else {
echo "Conversion from $sqlType to $dataType causes data corruption\n";
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
sqlsrv_query($conn, "TRUNCATE TABLE $tbname");
}
dropTable($conn, $tbname);
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing bit:
****Conversion from SQLSRV_SQLTYPE_BIT to bit is supported****
Testing tinyint:
****Conversion from SQLSRV_SQLTYPE_BIT to tinyint is supported****
****Conversion from SQLSRV_SQLTYPE_TINYINT to tinyint is supported****
Testing smallint:
****Conversion from SQLSRV_SQLTYPE_BIT to smallint is supported****
****Conversion from SQLSRV_SQLTYPE_TINYINT to smallint is supported****
****Conversion from SQLSRV_SQLTYPE_SMALLINT to smallint is supported****
Testing int:
****Conversion from SQLSRV_SQLTYPE_BIT to int is supported****
****Conversion from SQLSRV_SQLTYPE_TINYINT to int is supported****
****Conversion from SQLSRV_SQLTYPE_SMALLINT to int is supported****
****Conversion from SQLSRV_SQLTYPE_INT to int is supported****
Testing bigint:
****Conversion from SQLSRV_SQLTYPE_BIT to bigint is supported****
****Conversion from SQLSRV_SQLTYPE_TINYINT to bigint is supported****
****Conversion from SQLSRV_SQLTYPE_SMALLINT to bigint is supported****
****Conversion from SQLSRV_SQLTYPE_INT to bigint is supported****
****Conversion from SQLSRV_SQLTYPE_BIGINT to bigint is supported****

View file

@ -0,0 +1,270 @@
--TEST--
Test for inserting encrypted data of nchar types with different sizes
--DESCRIPTION--
Test implicit conversions between different nchar types of different sizes
With Always Encrypted, implicit conversion works if:
1. From input of SQLSRV_SQLTYPE_NCHAR(n) to a larger nchar(m) column where n <= m
2. From input of SQLSRV_SQLTYPE_NCHAR(n) to a larger nvarchar(m) column where n <= m (m can be max)
3. From input of SQLSRV_SQLTYPE_NVARCHAR(n) to a larger nchar(m) column where n <= m
4. From input of SQLSRV_SQLTYPE_NVARCHAR(n) to a larger nvarchar(m) column where n <= m (m can be max)
Without AlwaysEncrypted, implicit conversion between different binary types and sizes works
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
$dataTypes = array("nchar", "nvarchar", "nvarchar(max)");
$lengths = array(1, 8, 64, 512, 4000);
$sqlTypes = array("SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_NVARCHAR('max')");
$sqltypeLengths = $lengths;
$inputValue = "d";
$conn = AE\connect();
foreach($dataTypes as $dataType) {
$maxcol = strpos($dataType, "(max)");
foreach($lengths as $m) {
if ($maxcol !== false) {
$typeFull = $dataType;
} else {
$typeFull = "$dataType($m)";
}
echo "\nTesting $typeFull:\n";
// create table containing nchar(m) or nvarchar(m) columns
$tbname = "test_" . str_replace(array('(', ')'), '', $dataType) . $m;
$colMetaArr = array(new AE\ColumnMeta($typeFull, "c1", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// insert by specifying SQLSRV_SQLTYPE_NCHAR(n) or SQLSRV_SQLTYPE_NVARCHAR(n)
// with AE, should be successful as long as the SQLSRV_SQLTYPE length (n) is smaller than the column length (m)
foreach($sqlTypes as $sqlType) {
$maxsqltype = strpos($sqlType, "max");
foreach($sqltypeLengths as $n) {
if ($maxsqltype !== false) {
$sqltypeFull = $sqlType;
} else {
$sqltypeFull = "$sqlType($n)";
}
//insert a row
$input = new AE\BindParamOption($inputValue, null, null, $sqltypeFull);
$r;
$stmt = AE\insertRow($conn, $tbname, array("c1" => $input), $r, AE\INSERT_PREPARE_PARAMS);
// check the case when SQLSRV_SQLTYPE length (n) is greater than the column length (m)
// with AE: should not works
// without AE: should work
if (($n > $m || $maxsqltype) && !$maxcol) {
if (AE\isColEncrypted()) {
if ($r !== false) {
echo "AE: Conversion from $sqltypeFull to $typeFull should not be supported\n";
} else {
if (sqlsrv_errors()[0]['SQLSTATE'] != "22018") {
echo "AE: Conversion from $sqltypeFull to $typeFull expects an operand type clash error, actual error is incorrect\n";
var_dump(sqlsrv_errors());
}
}
} else {
if ($r === false) {
echo "Conversions from $sqltypeFull to $typeFull should be supported\n";
}
$sql = "SELECT c1 FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (trim($row['c1']) != $inputValue) {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
// check the case when SQLSRV_SQLTYPE length (n) is less than or equal to the column length (m)
// should work with AE or non AE
} else {
if ($r === false) {
echo "Conversion from $sqltypeFull to $typeFull should be supported\n";
} else {
$sql = "SELECT c1 FROM $tbname";
$stmt = sqlsrv_query($conn, $sql);
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if (trim($row['c1']) == $inputValue) {
echo "****Conversion from $sqltypeFull to $typeFull is supported****\n";
} else {
echo "Conversion from $sqltypeFull to $typeFull causes data corruption\n";
}
}
}
// cleanup
sqlsrv_free_stmt($stmt);
sqlsrv_query($conn, "TRUNCATE TABLE $tbname");
}
}
dropTable($conn, $tbname);
}
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing nchar(1):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nchar(1) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nchar(1) is supported****
Testing nchar(8):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nchar(8) is supported****
Testing nchar(64):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nchar(64) is supported****
Testing nchar(512):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nchar(512) is supported****
Testing nchar(4000):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nchar(4000) is supported****
Testing nvarchar(1):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(1) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(1) is supported****
Testing nvarchar(8):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(8) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(8) is supported****
Testing nvarchar(64):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(64) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(64) is supported****
Testing nvarchar(512):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(512) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(512) is supported****
Testing nvarchar(4000):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(4000) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nvarchar(4000) is supported****
Testing nvarchar(max):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
Testing nvarchar(max):
****Conversion from SQLSRV_SQLTYPE_NCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(1) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(8) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(64) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(512) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR(4000) to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****
****Conversion from SQLSRV_SQLTYPE_NVARCHAR('max') to nvarchar(max) is supported****