Merge pull request #715 from david-puglielli/ae-tests

AE tests for dates as strings, CAST conversions, and PHPTYPE retrieval
This commit is contained in:
David Puglielli 2018-03-22 15:40:53 -07:00 committed by GitHub
commit c8881946c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 1318 additions and 9 deletions

View file

@ -18,6 +18,15 @@ environment:
PHP_DEPSVER: 7.0
PHP_SDK: c:\projects\php
matrix:
- BUILD_PLATFORM: x64
TEST_PHP_SQL_SERVER: (local)\SQL2012SP1
SQL_INSTANCE: SQL2012SP1
PHP_VC: 14
PHP_MAJOR_VER: 7.1
PHP_MINOR_VER: latest
PHP_SDK_DIR: c:\projects\php\x64
PHP_INSTALL_DIR: c:\projects\php\x64\bin
platform: x64
- BUILD_PLATFORM: x86
TEST_PHP_SQL_SERVER: (local)\SQL2016
SQL_INSTANCE: SQL2016
@ -28,15 +37,6 @@ environment:
PHP_INSTALL_DIR: c:\projects\php\x86\bin
PHP_ZTS: --disable-zts
platform: x86
- BUILD_PLATFORM: x64
TEST_PHP_SQL_SERVER: (local)\SQL2012SP1
SQL_INSTANCE: SQL2012SP1
PHP_VC: 14
PHP_MAJOR_VER: 7.1
PHP_MINOR_VER: latest
PHP_SDK_DIR: c:\projects\php\x64
PHP_INSTALL_DIR: c:\projects\php\x64\bin
platform: x64
# PHP_MAJOR_VER is PHP major version to build (7.0, 7.1)
# PHP_MINOR_VER is PHP point release number (or latest for latest release)

View file

@ -0,0 +1,200 @@
--TEST--
Test insert data and fetch as all possible php types
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
require_once('tools.inc');
require_once('values.php');
// Set up the columns and build the insert query. Each data type has an
// AE-encrypted and a non-encrypted column side by side in the table.
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery, $strsize, $strsize2)
{
$columns = array();
$queryTypes = "(";
$queryTypesAE = "(";
$valuesString = "VALUES (";
$numTypes = sizeof($dataTypes);
for ($i = 0; $i < $numTypes; ++$i) {
// Replace parentheses for column names
$colname = str_replace(array("(", ",", ")"), array("_", "_", ""), $dataTypes[$i]);
$columns[] = new AE\ColumnMeta($dataTypes[$i], "c_".$colname."_AE");
$columns[] = new AE\ColumnMeta($dataTypes[$i], "c_".$colname, null, true, true);
$queryTypes .= "c_"."$colname, ";
$queryTypes .= "c_"."$colname"."_AE, ";
$valuesString .= "?, ?, ";
}
$queryTypes = substr($queryTypes, 0, -2).")";
$valuesString = substr($valuesString, 0, -2).")";
$insertQuery = "INSERT INTO $tableName ".$queryTypes." ".$valuesString;
}
$SQLSRV_PHPTYPE_CONST = array(SQLSRV_PHPTYPE_INT,
SQLSRV_PHPTYPE_DATETIME,
SQLSRV_PHPTYPE_FLOAT,
SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_BINARY),
SQLSRV_PHPTYPE_STREAM(SQLSRV_ENC_CHAR),
SQLSRV_PHPTYPE_STREAM("UTF-8"),
SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_BINARY),
SQLSRV_PHPTYPE_STRING(SQLSRV_ENC_CHAR),
SQLSRV_PHPTYPE_STRING("UTF-8")
);
// Two sizes for the string types so we can test conversion from
// a shorter type to a longer type
$strsize = 256;
$strsize2 = 384;
$dataTypes = array ("binary($strsize)", "varbinary($strsize)", "varbinary(max)", "char($strsize)",
"varchar($strsize)", "varchar(max)", "nchar($strsize)", "nvarchar($strsize)",
"nvarchar(max)", "datetime", "smalldatetime", "date", "time(5)", "datetimeoffset(5)",
"datetime2(5)", "decimal(28,4)", "numeric(32,4)", "float", "real", "bigint", "int",
"smallint", "tinyint", "bit",
"binary($strsize2)", "varbinary($strsize2)", "char($strsize2)",
"varchar($strsize2)", "nchar($strsize2)", "nvarchar($strsize2)",
"time", "datetimeoffset", "datetime2", "decimal(32,4)", "numeric(36,4)"
);
set_time_limit(0);
sqlsrv_configure('WarningsReturnAsErrors', 1);
// Connect
$connectionInfo = array("CharacterSet"=>"UTF-8");
$conn = AE\connect($connectionInfo);
if (!$conn) {
fatalError("Could not connect.\n");
}
$tableName = "type_conversion_table";
$columns = array();
$insertQuery = "";
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery, $strsize, $strsize2);
$stmt = AE\createTable($conn, $tableName, $columns);
if (!$stmt) {
fatalError("Failed to create table $tableName\n");
}
// The data we test against is in values.php
for ($v = 0; $v < sizeof($values);++$v)
{
// Each value must be inserted twice because the AE and non-AE column are side by side.
$testValues = array();
for ($i=0; $i<sizeof($values[$v]); ++$i) {
$testValues[] = $values[$v][$i];
$testValues[] = $values[$v][$i];
}
// Insert the data using sqlsrv_prepare()
// Insert one set of data for each PHPTYPE
$stmt = sqlsrv_prepare($conn, $insertQuery, $testValues);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_prepare failed\n");
}
for ($i = 0; $i < sizeof($SQLSRV_PHPTYPE_CONST); ++$i) {
if (sqlsrv_execute($stmt) == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_execute failed\n");
}
}
$selectQuery = "SELECT * FROM $tableName";
// Two select statements for selection using
// sqlsrv_get_field and sqlsrv_fetch_array
$stmt = sqlsrv_query($conn, $selectQuery);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("First sqlsrv_prepare failed\n");
}
$stmt2 = sqlsrv_query($conn, $selectQuery);
if ($stmt2 == false) {
print_r(sqlsrv_errors());
fatalError("Second sqlsrv_prepare failed\n");
}
$numFields = sqlsrv_num_fields($stmt);
$i = 0;
$valueAE = null;
$valueFromArrayAE = null;
while ($result = sqlsrv_fetch($stmt)) {
$dataArray = sqlsrv_fetch_array($stmt2, SQLSRV_FETCH_NUMERIC);
for ($j = 0; $j < $numFields; $j++) {
$value = sqlsrv_get_field($stmt, $j, $SQLSRV_PHPTYPE_CONST[$i]);
$valueFromArray = $dataArray[$j];
// PHPTYPE_STREAM returns a PHP resource, so check the type
if (is_resource($value)) $value = get_resource_type($value);
// For each type, the AE values come first and non-AE values second
// So let's do the comparison every second field
if ($j%2 == 0) {
$valueAE = $value;
$valueFromArrayAE = $valueFromArray;
} elseif ($j%2 == 1) {
// If returning a DateTime PHP type from a date only SQL type,
// PHP adds the current timestamp to make a DateTime object,
// and in this case the AE and non-AE times may be off by a
// fraction of a second since they are retrieved at ever-so-slightly
// different times. This not a test-failing discrepancy, so
// below the DateTime objects are made equal again for the next if
// block.
if ($value instanceof DateTime) {
// date_diff returns a DateInterval object, and s is
// the difference in seconds. s should be zero because
// the difference should be just a fraction of a second.
$datediff = date_diff($value, $valueAE);
$diff = $datediff->s;
if ($diff == 0) {
$value = $valueAE;
}
}
if ($valueAE != $value or $valueFromArrayAE != $valueFromArray) {
echo "Values do not match! PHPType $i Field $j\n";
print_r($valueAE);echo "\n";
print_r($value);echo "\n";
print_r($valueFromArrayAE);echo "\n";
print_r($valueFromArray);echo "\n";
print_r(sqlsrv_errors());
fatalError("Test failed, values do not match.\n");
}
}
}
++$i;
}
sqlsrv_free_stmt($stmt);
sqlsrv_free_stmt($stmt2);
$deleteQuery = "DELETE FROM $tableName";
$stmt = sqlsrv_query($conn, $deleteQuery);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("Delete statement failed");
}
sqlsrv_free_stmt($stmt);
}
dropTable($conn, $tableName);
sqlsrv_close($conn);
echo "Test successful\n";
?>
--EXPECT--
Test successful

View file

@ -0,0 +1,331 @@
--TEST--
Test fetching data by conversion with CAST in the SELECT statement
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
require_once('tools.inc');
require_once('values.php');
// These are the errors we expect to see if a conversion fails.
// 22001 String data is right-truncated
// 22003 Numeric value out of range/Overflow converting to numeric type
// 22007 Conversion (date/time from string) failed
// 22018 Conversion not allowed
// 42S22 Column not found
// 6522 .NET Framework error in hierarchyId construction
// 8114 Error converting binary/string type to numeric type
// 8169 Error converting from string to uniqueID
function checkAcceptableErrors(&$convError)
{
if ($convError[0][0] != '22018' and
$convError[0][0] != '22001' and
$convError[0][0] != '22003' and
$convError[0][0] != '22007' and
$convError[0][0] != '42S22' and
$convError[0][1] != '6522' and
$convError[0][1] != '8114' and
$convError[0][1] != '8169') {
print_r($convError);
fatalError("Conversion failed with unexpected error message. i=$i, j=$j, v=$v\n");
}
}
// Set up the columns and build the insert query. Each data type has an
// AE-encrypted and a non-encrypted column side by side in the table.
function FormulateSetupQuery($tableName, &$dataTypes, &$columns, &$insertQuery, $strsize, $strsize2)
{
$columns = array();
$columnsInQuery = "(";
$valuesString = "VALUES (";
$numTypes = sizeof($dataTypes);
for ($i = 0; $i < $numTypes; ++$i) {
// Replace parentheses for column names
$colname = str_replace(array("(", ",", ")"), array("_", "_", ""), $dataTypes[$i]);
$columns[] = new AE\ColumnMeta($dataTypes[$i], "c_".$colname."_AE"); // encrypted column
$columns[] = new AE\ColumnMeta($dataTypes[$i], "c_".$colname, null, true, true);// non-encrypted column
$columnsInQuery .= "c_"."$colname, ";
$columnsInQuery .= "c_"."$colname"."_AE, ";
$valuesString .= "?, ?, ";
}
$columnsInQuery = substr($columnsInQuery, 0, -2).")";
$valuesString = substr($valuesString, 0, -2).")";
$insertQuery = "INSERT INTO $tableName ".$columnsInQuery." ".$valuesString;
}
// Build the select queries. We want every combination of types for conversion
// testing, so the matrix of queries selects every type from every column
// and convert using CAST.
function FormulateSelectQuery($tableName, &$selectQuery, &$selectQueryAE, &$dataTypes, $strsize, $strsize2)
{
$numTypes = sizeof($dataTypes);
for ($i = 0; $i < $numTypes; ++$i) {
$selectQuery[] = array();
$colnamei = str_replace(array("(", ",", ")"), array("_", "_", ""), $dataTypes[$i]);
for ($j = 0; $j < sizeof($dataTypes); ++$j) {
$selectQuery[$i][] = "SELECT CAST(c_".$colnamei." AS $dataTypes[$j]) FROM $tableName";
$selectQueryAE[$i][] = "SELECT CAST(c_".$colnamei."_AE AS $dataTypes[$j]) FROM $tableName";
}
}
}
// Two sizes for the string types so we can test conversion from
// a shorter type to a longer type
$strsize = 256;
$strsize2 = 384;
$dataTypes = array ("binary($strsize)", "varbinary($strsize)", "varbinary(max)", "char($strsize)",
"varchar($strsize)", "varchar(max)", "nchar($strsize)", "nvarchar($strsize)",
"nvarchar(max)", "datetime", "smalldatetime", "date", "time(5)", "datetimeoffset(5)",
"datetime2(5)", "decimal(28,4)", "numeric(32,4)", "float", "real", "bigint", "int",
"smallint", "tinyint", "bit",
"binary($strsize2)", "varbinary($strsize2)", "char($strsize2)",
"varchar($strsize2)", "nchar($strsize2)", "nvarchar($strsize2)",
"time", "datetimeoffset", "datetime2", "decimal(32,4)", "numeric(36,4)"
);
// Conversion matrix for SQL types, based on the conversion chart
// at https://www.microsoft.com/en-us/download/details.aspx?id=35834
// i = implicit conversion
// e = explicit conversion
// x = conversion not allowed
// @ = not applicable
// c = explicit CAST required
// m = misc
$conversionMatrix = array(array('@','i','i','i','i','i','i','i','i','i','i','e','e','e','e','i','i','x','x','i','i','i','i','i','i','i','i','i','i','i','e','e','e','i','i'),//binary
array('i','@','i','i','i','i','i','i','i','i','i','e','e','e','e','i','i','x','x','i','i','i','i','i','i','i','i','i','i','i','e','e','e','i','i'),//varbinary
array('i','i','@','i','i','i','i','i','i','i','i','e','e','e','e','i','i','x','x','i','i','i','i','i','i','i','i','i','i','i','e','e','e','i','i'),//varbinary(max)
array('e','e','e','@','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','i','i','i','i','i','i'),//char
array('e','e','e','i','@','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','i','i','i','i','i','i'),//varchar
array('e','e','e','i','i','@','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','i','i','i','i','i','i'),//varchar(max)
array('e','e','e','i','i','i','@','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','i','i','i','i','i','i'),//nchar
array('e','e','e','i','i','i','i','@','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','i','i','i','i','i','i'),//nvarchar
array('e','e','e','i','i','i','i','i','@','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','i','i','i','i','i','i'),//nvarchar(max)
array('e','e','e','i','i','i','i','i','i','@','i','i','i','i','i','e','e','e','e','e','e','e','e','e','e','e','i','i','i','i','i','i','i','e','e'),//datetime
array('e','e','e','i','i','i','i','i','i','i','@','i','i','i','i','e','e','e','e','e','e','e','e','e','e','e','i','i','i','i','i','i','i','e','e'),//samlldatetime
array('e','e','e','i','i','i','i','i','i','i','i','@','x','i','i','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','x','i','i','x','x'),//date
array('e','e','e','i','i','i','i','i','i','i','i','x','@','i','i','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','i','i','i','x','x'),//time
array('e','e','e','i','i','i','i','i','i','i','i','i','i','@','i','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','i','i','i','x','x'),//datetimeoffset
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','@','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','i','i','i','x','x'),//datetime2
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','c','c','i','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','c','c'),//decimal
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','c','c','i','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','c','c'),//numeric
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','c','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','i','i'),//float
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','i','@','i','i','i','i','i','i','i','i','i','i','i','x','x','x','i','i'),//real
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','i','i','@','i','i','i','i','i','i','i','i','i','i','x','x','x','i','i'),//bigint
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','i','i','i','@','i','i','i','i','i','i','i','i','i','x','x','x','i','i'),//int
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','i','i','i','i','@','i','i','i','i','i','i','i','i','x','x','x','i','i'),//smallint
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','i','i','i','i','i','@','i','i','i','i','i','i','i','x','x','x','i','i'),//tinyint
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','i','i','i','i','i','i','i','i','@','i','i','i','i','i','i','x','x','x','i','i'),//bit
array('i','i','i','i','i','i','i','i','i','i','i','e','e','e','e','i','i','x','x','i','i','i','i','i','@','i','i','i','i','i','e','e','e','i','i'),//binary
array('i','i','i','i','i','i','i','i','i','i','i','e','e','e','e','i','i','x','x','i','i','i','i','i','i','@','i','i','i','i','e','e','e','i','i'),//varbinary
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','@','i','i','i','i','i','i','i','i'),//char
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','@','i','i','i','i','i','i','i'),//varchar
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','@','i','i','i','i','i','i'),//nchar
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','i','e','e','i','i','i','@','i','i','i','i','i'),//nvarchar
array('e','e','e','i','i','i','i','i','i','i','i','x','i','i','i','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','@','i','i','x','x'),//time
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','i','@','i','x','x'),//datetimeoffset
array('e','e','e','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','x','x','x','x','x','e','e','i','i','i','i','i','i','@','x','x'),//datetime2
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','c','c','i','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','c','c'),//decimal
array('i','i','i','i','i','i','i','i','i','i','i','x','x','x','x','c','c','i','i','i','i','i','i','i','i','i','i','i','i','i','x','x','x','c','c'),//numeric
);
// The conversion matrix for AE is more restrictive
// y = allowed conversion
// x = not allowed
$conversionMatrixAE = array(array('y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x','x','x'),//binary
array('y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x','x','x'),//varbinary
array('x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//varbinary(max)
array('x','x','x','y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x'),//char
array('x','x','x','y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x'),//varchar
array('x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//varchar(max)
array('x','x','x','x','x','x','y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x'),//nchar
array('x','x','x','x','x','x','y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x'),//nvarchar
array('x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//nvarchar(max)
array('x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//datetime
array('x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//samlldatetime
array('x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//date
array('x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x'),//time
array('x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x'),//datetimeoffset
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x'),//datetime2
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//decimal
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x'),//numeric
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//float
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//real
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//bigint
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x'),//int
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','y','x','x','x','x','x','x','x','x','x','x','x','x','x'),//smallint
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','y','y','x','x','x','x','x','x','x','x','x','x','x','x'),//tinyint
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','y','y','y','x','x','x','x','x','x','x','x','x','x','x'),//bit
array('x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x','x','x'),//binary
array('x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x','x','x'),//varbinary
array('x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x'),//char
array('x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x','x','x'),//varchar
array('x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x'),//nchar
array('x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','y','x','x','x','x','x'),//nvarchar
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x'),//time
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x'),//datetimeoffset
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x'),//datetime2
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y','x'),//decimal
array('x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','x','y'),//numeric
);
set_time_limit(0);
sqlsrv_configure('WarningsReturnAsErrors', 1);
$connectionInfo = array("CharacterSet"=>"UTF-8");
$conn = AE\connect($connectionInfo);
if (!$conn) {
fatalError("Could not connect.\n");
}
$tableName = "type_conversion_table";
$columns = array();
$insertQuery = "";
FormulateSetupQuery($tableName, $dataTypes, $columns, $insertQuery, $strsize, $strsize2);
$stmt = AE\createTable($conn, $tableName, $columns);
if (!$stmt) {
fatalError("Failed to create table $tableName\n");
}
// The data we test against is in values.php
for ($v = 0; $v < sizeof($values); ++$v)
{
// Each value must be inserted twice because the AE and non-AE column are side by side.
$testValues = array();
for ($i = 0; $i < sizeof($values[$v]); ++$i) {
$testValues[] = $values[$v][$i];
$testValues[] = $values[$v][$i];
}
// Insert the data using sqlsrv_prepare()
$stmt = sqlsrv_prepare($conn, $insertQuery, $testValues);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_prepare failed\n");
}
if (!sqlsrv_execute($stmt)) {
print_r(sqlsrv_errors());
fatalError("sqlsrv_execute failed\n");
}
sqlsrv_free_stmt($stmt);
// Formulate the matrix of SELECT queries and iterate over each index.
$selectQuery = array();
$selectQueryAE = array();
FormulateSelectQuery($tableName, $selectQuery, $selectQueryAE, $dataTypes, $strsize, $strsize2);
for ($i = 8; $i < sizeof($dataTypes); ++$i) {
for ($j = 0; $j < sizeof($dataTypes); ++$j) {
$stmt = sqlsrv_query($conn, $selectQuery[$i][$j]);
if ($stmt == false) {
$convError = sqlsrv_errors();
checkAcceptableErrors($convError);
if (AE\isDataEncrypted()) {
$stmtAE = sqlsrv_query($conn, $selectQueryAE[$i][$j]);
$convError = sqlsrv_errors();
// if the non-AE conversion fails, certainly the AE conversion
// should fail but only with error 22018.
if ($stmtAE != false) fatalError("AE conversion should have failed. i=$i, j=$j, v=$v\n\n");
if ($convError[0][0] != '22018') {
print_r($convError);
fatalError("AE conversion failed with unexpected error message. i=$i, j=$j, v=$v\n");
}
}
} else {
if ($conversionMatrix[$i][$j] == 'x') fatalError("Conversion succeeded, should have failed. i=$i, j=$j, v=$v\n");
if (AE\isDataEncrypted()) {
$stmtAE = sqlsrv_query($conn, $selectQueryAE[$i][$j]);
// Check every combination of statement value and conversion.
// The last else if block covers the case where the select
// query worked and the retrieved values are compared.
if ($stmtAE == false and $conversionMatrixAE[$i][$j] == 'x') {
$convError = sqlsrv_errors();
if ($convError[0][0] != '22018') {
print_r($convError);
fatalError("AE conversion failed with unexpected error message. i=$i, j=$j, v=$v\n");
}
} elseif ($stmtAE == false and $conversionMatrixAE[$i][$j] == 'y') {
print_r(sqlsrv_errors());
fatalError("AE conversion failed, should have succeeded. i=$i, j=$j, v=$v\n");
} elseif ($stmtAE != false and $conversionMatrixAE[$i][$j] == 'x') {
fatalError("AE conversion succeeded, should have failed. i=$i, j=$j, v=$v\n");
} elseif ($stmtAE != false and $conversionMatrixAE[$i][$j] == 'y') {
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_NUMERIC);
$rowAE = sqlsrv_fetch_array($stmtAE, SQLSRV_FETCH_NUMERIC);
// rtrim strips whitespace from the end of the string, which
// takes care of a bug where some conversions lead to extraneous
// whitespace padding the end of the string
if (is_string($row[0])) {
$row[0] = rtrim($row[0]);
$rowAE[0] = rtrim($rowAE[0]);
}
if ($row[0] != $rowAE[0]) {
echo "Values do not match! i=$i, j=$j, v=$v\n";
print_r($row[0]);
print_r($rowAE[0]);
print_r($selectQuery[$i][$j]);echo "\n";
print_r($selectQueryAE[$i][$j]);echo "\n";
fatalError("Test failed, values do not match\n");
}
}
}
}
}
}
$deleteQuery = "DELETE FROM $tableName";
$stmt = sqlsrv_query($conn, $deleteQuery);
if ($stmt == false) {
print_r(sqlsrv_errors());
fatalError("Delete statement failed");
}
echo "Step $v done\n";
}
dropTable($conn, $tableName);
sqlsrv_close($conn);
echo "Test successful\n";
?>
--EXPECT--
Step 0 done
Step 1 done
Step 2 done
Step 3 done
Step 4 done
Step 5 done
Step 6 done
Step 7 done
Step 8 done
Step 9 done
Step 10 done
Step 11 done
Step 12 done
Step 13 done
Step 14 done
Step 15 done
Step 16 done
Step 17 done
Step 18 done
Step 19 done
Step 20 done
Test successful

File diff suppressed because one or more lines are too long