diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_binary_size.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_binary_size.phpt new file mode 100644 index 00000000..130c9773 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_binary_size.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_char_size.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_char_size.phpt new file mode 100644 index 00000000..63d1e2e3 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_char_size.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_datetime.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_datetime.phpt new file mode 100644 index 00000000..daf255d1 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_datetime.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_datetime_precision.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_datetime_precision.phpt new file mode 100644 index 00000000..a636a67a --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_datetime_precision.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_decimal_precision.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_decimal_precision.phpt new file mode 100644 index 00000000..f89f5477 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_decimal_precision.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_float_bits.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_float_bits.phpt new file mode 100644 index 00000000..c1c4ae63 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_float_bits.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_nchar_size.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_nchar_size.phpt new file mode 100644 index 00000000..768d371e --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_nchar_size.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_numeric.phpt b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_numeric.phpt new file mode 100644 index 00000000..4bb3f928 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_bindColumn_pdoparam_numeric.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_binary_size.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_binary_size.phpt new file mode 100644 index 00000000..150ce6aa --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_binary_size.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_char_size.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_char_size.phpt new file mode 100644 index 00000000..a577e6f1 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_char_size.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime.phpt index df3fbfc5..72c1ef3a 100644 --- a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime.phpt +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime.phpt @@ -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-- --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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime_precision.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime_precision.phpt new file mode 100644 index 00000000..a3db5c7f --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_datetime_precision.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_decimal_precision.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_decimal_precision.phpt new file mode 100644 index 00000000..4295c0c2 --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_decimal_precision.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_float_bits.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_float_bits.phpt new file mode 100644 index 00000000..534595ed --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_float_bits.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_nchar_size.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_nchar_size.phpt new file mode 100644 index 00000000..03ca55cd --- /dev/null +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_nchar_size.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_numeric.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_numeric.phpt index 6dc7f755..541beeec 100644 --- a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_numeric.phpt +++ b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_numeric.phpt @@ -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-- --FILE-- 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**** \ No newline at end of file diff --git a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_string.phpt b/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_string.phpt deleted file mode 100644 index 44ec7d0a..00000000 --- a/test/functional/pdo_sqlsrv/pdo_ae_insert_pdoparam_string.phpt +++ /dev/null @@ -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-- - ---FILE-- - 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). diff --git a/test/functional/sqlsrv/MsHelper.inc b/test/functional/sqlsrv/MsHelper.inc index cf4ad82b..e0329855 100644 --- a/test/functional/sqlsrv/MsHelper.inc +++ b/test/functional/sqlsrv/MsHelper.inc @@ -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 { diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_binary_size.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_binary_size.phpt new file mode 100644 index 00000000..84e90961 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_binary_size.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_char_size.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_char_size.phpt new file mode 100644 index 00000000..8e98fb81 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_char_size.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_datetime_precision.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_datetime_precision.phpt new file mode 100644 index 00000000..4d962d94 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_datetime_precision.phpt @@ -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-- + +--FILE-- +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**** \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_decimal_precision.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_decimal_precision.phpt new file mode 100644 index 00000000..3fc7cd37 --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_decimal_precision.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_float_bits.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_float_bits.phpt new file mode 100644 index 00000000..0d0da7ad --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_float_bits.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_int_conv.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_int_conv.phpt new file mode 100644 index 00000000..40b6827d --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_int_conv.phpt @@ -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-- + +--FILE-- + 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**** \ No newline at end of file diff --git a/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_nchar_size.phpt b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_nchar_size.phpt new file mode 100644 index 00000000..484cf2fa --- /dev/null +++ b/test/functional/sqlsrv/sqlsrv_ae_insert_sqltype_nchar_size.phpt @@ -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-- + +--FILE-- + $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**** \ No newline at end of file