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:
commit
c8881946c5
18
appveyor.yml
18
appveyor.yml
|
@ -18,6 +18,15 @@ environment:
|
||||||
PHP_DEPSVER: 7.0
|
PHP_DEPSVER: 7.0
|
||||||
PHP_SDK: c:\projects\php
|
PHP_SDK: c:\projects\php
|
||||||
matrix:
|
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
|
- BUILD_PLATFORM: x86
|
||||||
TEST_PHP_SQL_SERVER: (local)\SQL2016
|
TEST_PHP_SQL_SERVER: (local)\SQL2016
|
||||||
SQL_INSTANCE: SQL2016
|
SQL_INSTANCE: SQL2016
|
||||||
|
@ -28,15 +37,6 @@ environment:
|
||||||
PHP_INSTALL_DIR: c:\projects\php\x86\bin
|
PHP_INSTALL_DIR: c:\projects\php\x86\bin
|
||||||
PHP_ZTS: --disable-zts
|
PHP_ZTS: --disable-zts
|
||||||
platform: x86
|
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_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)
|
# PHP_MINOR_VER is PHP point release number (or latest for latest release)
|
||||||
|
|
200
test/functional/sqlsrv/sqlsrv_ae_fetch_phptypes.phpt
Normal file
200
test/functional/sqlsrv/sqlsrv_ae_fetch_phptypes.phpt
Normal 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
|
331
test/functional/sqlsrv/sqlsrv_ae_type_conversion_select.phpt
Normal file
331
test/functional/sqlsrv/sqlsrv_ae_type_conversion_select.phpt
Normal 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
|
778
test/functional/sqlsrv/values.php
Normal file
778
test/functional/sqlsrv/values.php
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in a new issue