sqlsrv tests for output parms with sqltypes (#720)

* sqlsrv tests for output parms with sqltypes
This commit is contained in:
v-susanh 2018-03-15 22:29:41 -07:00 committed by GitHub
parent 8ed2aeb29a
commit af54c9eaeb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 634 additions and 120 deletions

View file

@ -1,113 +1,170 @@
<?php
// exact numerics
$bigint_params = array( 2147483648, -922337203685479936, 922337203685479936, -2147583649, 461168601735364608, -461168601735364608 );
$int_params = array( 32768, -2147483647, 2147483647, -32769, 1073725440, -1073725440 );
$smallint_params = array( 256, -32767, 32767, -1, 16256, -16256 );
$tinyint_params = array( 128, 0, 255, 96, 64, 162 );
$decimal_params = array( 21474.83648, -9223372036854.80000, 9223372036854.80000, -21475.83649, -4611686017353.64608, -4611686017353.64608 );
$numeric_params = array( 0.32768, -21474.83647, 21474.83647, -0.32769, 10737.25440, -10737.25440 );
$money_params = array( 214748.3648, -92233720368548.0000, 92233720368548.0000, -214758.3649, 46116860173536.608, -46116860173536.608 );
$smallmoney_params = array( 0, -214748.3647, 214748.3647, 161061.2736, 107374.1824, -107374.1824 );
$bit_params = array( 0, 1, 0, 1, 0, 1 );
// approximate numerics
$float_params = array( 21474.83648, -9223372036.8548, 9223372036.8548, -21475, 4611686017, -4611686017 );
$real_params = array( 0, -2147.483, 2147.483, 1610, 1073, -1073 );
// date and time
$date_params = array( '1900-01-01', '0001-01-01', '9999-12-31', '5000-07-15', '2500-04-08', '7500-10-23' );
$datetime2_params = array( '1900-01-01 00:00:00', '0001-01-01 00:00:00', '9999-12-31 23:59:59.123456', '5000-07-15 12:30:30.5555', '2500-04-08 06:15:15.33', '7500-10-23 18:45:45.888888' );
$datetime_params = array( '1900-01-01 00:00:00', '1753-01-01 00:00:00', '9999-12-31 23:59:59.997', '5000-07-15 12:30:30.5', '2500-04-08 06:15:15.33', '7500-10-23 18:45:45.888' );
$datetimeoffset_params = array( '1900-01-01 00:00:00 +01:00', '0001-01-01 00:00:00 -14:00', '9999-12-31 23:59:59.123456+14:00', '5000-07-15 12:30:30.55 -03:00', '2500-04-08 06:15:15.3333 -07:00', '7500-10-23 18:45:45.888888 +07:00' );
$smalldatetime_params = array( '1900-01-01 00:00:00', '1900-01-01 00:00:00', '2079-06-05 23:59:00', '1990-07-15 12:30:00', '1945-04-08 06:15:00', '2000-10-23 18:45:00' );
$time_params = array( '00:00:00', '00:00:00.0000000', '23:59:59.123456', '12:30:30.5555', '06:15:15.33', '18:45:45.888888' );
// character strings
$char_params = array( 'Fixed', '-leng', 'th, n', 'on-Un', 'icode', 'strin' );
$varchar_params = array( 'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.',
'Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.',
'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.',
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.',
'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.' );
// unicode character strings
$nchar_params = array( 'Fixed', '-leng', 'th Un', 'icode', 'strin', 'g dat' );
$nvarchar_params = array( 'max indicates that the maximum storage size is 2^31-1 bytes (2 GB).',
'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).',
'Otherwise, the implicit conversion will result in a Unicode large-value (max).',
'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.',
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.' );
// binary strings
$binary_params = array( 'Fixed', '-leng', 'th, n', 'on-Un', 'icode', 'strin' );
$varbinary_params = array( 'Variable-length, non-', 'Unicode string data. n', 'defines the string length', 'and can be a value from 1', 'through 8,000.', 'The storage size is the' );
$varbinarymax_params = array( 'max indicates that the maximum storage size is 2^31-1 bytes (2 GB)',
'Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.',
'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.',
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.',
'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.' );
// Array containing all SQLSRV_SQLTYPE_ types to pass into a bind param prepare statement
$sqlTypes = array(
'SQLSRV_SQLTYPE_BIGINT',
'SQLSRV_SQLTYPE_BINARY',
'SQLSRV_SQLTYPE_BIT',
'SQLSRV_SQLTYPE_CHAR',
'SQLSRV_SQLTYPE_DATE',
'SQLSRV_SQLTYPE_DATETIME',
'SQLSRV_SQLTYPE_DATETIME2',
'SQLSRV_SQLTYPE_DATETIMEOFFSET',
'SQLSRV_SQLTYPE_DECIMAL',
'SQLSRV_SQLTYPE_FLOAT',
'SQLSRV_SQLTYPE_IMAGE',
'SQLSRV_SQLTYPE_INT',
'SQLSRV_SQLTYPE_MONEY',
'SQLSRV_SQLTYPE_NCHAR',
'SQLSRV_SQLTYPE_NUMERIC',
'SQLSRV_SQLTYPE_NVARCHAR',
'SQLSRV_SQLTYPE_NTEXT',
'SQLSRV_SQLTYPE_REAL',
'SQLSRV_SQLTYPE_SMALLDATETIME',
'SQLSRV_SQLTYPE_SMALLINT',
'SQLSRV_SQLTYPE_SMALLMONEY',
'SQLSRV_SQLTYPE_TEXT',
'SQLSRV_SQLTYPE_TIME',
'SQLSRV_SQLTYPE_TIMESTAMP',
'SQLSRV_SQLTYPE_TINYINT',
'SQLSRV_SQLTYPE_UNIQUEIDENTIFIER',
'SQLSRV_SQLTYPE_VARBINARY',
'SQLSRV_SQLTYPE_VARCHAR',
'SQLSRV_SQLTYPE_XML'
);
// Checks if the current error is the incompatible types error
// if so, state which sql type is incompatible with which data type
function is_incompatible_types_error( $dataType, $sqlType )
{
$errors = sqlsrv_errors();
foreach ( $errors as $error )
{
// 22018 is the SQLSTATE for the operand crash error for incompatible types
if ( $error['SQLSTATE'] == 22018 )
{
echo "Encrypted $sqlType is incompatible with encrypted $dataType\n";
}
}
}
function get_default_size_prec( $sqlType )
{
if ( $sqlType == 'SQLSRV_SQLTYPE_DECIMAL' )
$sqlType .= "(18, 5)";
elseif ( $sqlType == 'SQLSRV_SQLTYPE_NUMERIC' )
$sqlType .= "(10, 5)";
elseif ( $sqlType == 'SQLSRV_SQLTYPE_CHAR' || $sqlType == 'SQLSRV_SQLTYPE_NCHAR' )
$sqlType .= "(5)";
return $sqlType;
}
?>
<?php
// exact numerics
$bigint_params = array( 2147483648, -922337203685479936, 922337203685479936, -2147583649, 461168601735364608, -461168601735364608 );
$int_params = array( 32768, -2147483647, 2147483647, -32769, 1073725440, -1073725440 );
$smallint_params = array( 256, -32767, 32767, -1, 16256, -16256 );
$tinyint_params = array( 128, 0, 255, 96, 64, 162 );
$decimal_params = array( 21474.83648, -9223372036854.80000, 9223372036854.80000, -21475.83649, -4611686017353.64608, -4611686017353.64608 );
$numeric_params = array( 0.32768, -21474.83647, 21474.83647, -0.32769, 10737.25440, -10737.25440 );
$money_params = array( 214748.3648, -92233720368548.0000, 92233720368548.0000, -214758.3649, 46116860173536.608, -46116860173536.608 );
$smallmoney_params = array( 0, -214748.3647, 214748.3647, 161061.2736, 107374.1824, -107374.1824 );
$bit_params = array( 0, 1, 0, 1, 0, 1 );
// approximate numerics
$float_params = array( 21474.83648, -9223372036.8548, 9223372036.8548, -21475, 4611686017, -4611686017 );
$real_params = array( 0, -2147.483, 2147.483, 1610, 1073, -1073 );
// date and time
$date_params = array( '1900-01-01', '0001-01-01', '9999-12-31', '5000-07-15', '2500-04-08', '7500-10-23' );
$datetime2_params = array( '1900-01-01 00:00:00', '0001-01-01 00:00:00', '9999-12-31 23:59:59.123456', '5000-07-15 12:30:30.5555', '2500-04-08 06:15:15.33', '7500-10-23 18:45:45.888888' );
$datetime_params = array( '1900-01-01 00:00:00', '1753-01-01 00:00:00', '9999-12-31 23:59:59.997', '5000-07-15 12:30:30.5', '2500-04-08 06:15:15.33', '7500-10-23 18:45:45.888' );
$datetimeoffset_params = array( '1900-01-01 00:00:00 +01:00', '0001-01-01 00:00:00 -14:00', '9999-12-31 23:59:59.123456+14:00', '5000-07-15 12:30:30.55 -03:00', '2500-04-08 06:15:15.3333 -07:00', '7500-10-23 18:45:45.888888 +07:00' );
$smalldatetime_params = array( '1900-01-01 00:00:00', '1900-01-01 00:00:00', '2079-06-05 23:59:00', '1990-07-15 12:30:00', '1945-04-08 06:15:00', '2000-10-23 18:45:00' );
$time_params = array( '00:00:00', '00:00:00.0000000', '23:59:59.123456', '12:30:30.5555', '06:15:15.33', '18:45:45.888888' );
// character strings
$char_params = array( 'Fixed', '-leng', 'th, n', 'on-Un', 'icode', 'strin' );
$varchar_params = array( 'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.',
'Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.',
'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.',
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.',
'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.' );
// unicode character strings
$nchar_params = array( 'Fixed', '-leng', 'th Un', 'icode', 'strin', 'g dat' );
$nvarchar_params = array( 'max indicates that the maximum storage size is 2^31-1 bytes (2 GB).',
'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).',
'Otherwise, the implicit conversion will result in a Unicode large-value (max).',
'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.',
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.' );
// binary strings
$binary_params = array( 'Fixed', '-leng', 'th, n', 'on-Un', 'icode', 'strin' );
$varbinary_params = array( 'Variable-length, non-', 'Unicode string data. n', 'defines the string length', 'and can be a value from 1', 'through 8,000.', 'The storage size is the' );
$varbinarymax_params = array( 'max indicates that the maximum storage size is 2^31-1 bytes (2 GB)',
'Use varchar(max) when the sizes of the column data entries vary considerably, and the size might exceed 8,000 bytes.',
'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.',
'This can create an implicit limit to the number of non-null varchar(max) or nvarchar(max) columns that can be created in a table.',
'No special error is provided when the table is created (beyond the usual warning that the maximum row size exceeds the allowed maximum of 8060 bytes) or at the time of data insertion.',
'This large row size can cause errors (such as error 512) during some normal operations, such as a clustered index key update, or sorts of the full column set, which users cannot anticipate until performing an operation.' );
// Array containing all SQLSRV_SQLTYPE_ types to pass into a bind param prepare statement
$sqlTypes = array(
'SQLSRV_SQLTYPE_BIGINT',
'SQLSRV_SQLTYPE_BINARY',
'SQLSRV_SQLTYPE_BIT',
'SQLSRV_SQLTYPE_CHAR',
'SQLSRV_SQLTYPE_DATE',
'SQLSRV_SQLTYPE_DATETIME',
'SQLSRV_SQLTYPE_DATETIME2',
'SQLSRV_SQLTYPE_DATETIMEOFFSET',
'SQLSRV_SQLTYPE_DECIMAL',
'SQLSRV_SQLTYPE_FLOAT',
'SQLSRV_SQLTYPE_IMAGE',
'SQLSRV_SQLTYPE_INT',
'SQLSRV_SQLTYPE_MONEY',
'SQLSRV_SQLTYPE_NCHAR',
'SQLSRV_SQLTYPE_NUMERIC',
'SQLSRV_SQLTYPE_NVARCHAR',
'SQLSRV_SQLTYPE_NTEXT',
'SQLSRV_SQLTYPE_REAL',
'SQLSRV_SQLTYPE_SMALLDATETIME',
'SQLSRV_SQLTYPE_SMALLINT',
'SQLSRV_SQLTYPE_SMALLMONEY',
'SQLSRV_SQLTYPE_TEXT',
'SQLSRV_SQLTYPE_TIME',
'SQLSRV_SQLTYPE_TIMESTAMP',
'SQLSRV_SQLTYPE_TINYINT',
'SQLSRV_SQLTYPE_UNIQUEIDENTIFIER',
'SQLSRV_SQLTYPE_VARBINARY',
'SQLSRV_SQLTYPE_VARCHAR',
'SQLSRV_SQLTYPE_XML'
);
// Checks if the current error is the incompatible types error
// if so, state which sql type is incompatible with which data type
function is_incompatible_types_error( $dataType, $sqlType )
{
$errors = sqlsrv_errors();
foreach ( $errors as $error )
{
// 22018 is the SQLSTATE for the operand crash error for incompatible types
if ( $error['SQLSTATE'] == 22018 )
{
echo "Encrypted $sqlType is incompatible with encrypted $dataType\n";
}
}
}
function get_default_size_prec( $sqlType )
{
if ( $sqlType == 'SQLSRV_SQLTYPE_DECIMAL' )
$sqlType .= "(18, 5)";
elseif ( $sqlType == 'SQLSRV_SQLTYPE_NUMERIC' )
$sqlType .= "(10, 5)";
elseif ( $sqlType == 'SQLSRV_SQLTYPE_CHAR' || $sqlType == 'SQLSRV_SQLTYPE_NCHAR' )
$sqlType .= "(5)";
return $sqlType;
}
// get sqlType constant value from string
function get_sqlType_constant( $sqlType )
{
switch ( $sqlType ) {
case 'SQLSRV_SQLTYPE_BIGINT':
case 'SQLSRV_SQLTYPE_BINARY':
case 'SQLSRV_SQLTYPE_BIT':
case 'SQLSRV_SQLTYPE_DATE':
case 'SQLSRV_SQLTYPE_DATETIME':
case 'SQLSRV_SQLTYPE_DATETIME2':
case 'SQLSRV_SQLTYPE_DATETIMEOFFSET':
case 'SQLSRV_SQLTYPE_FLOAT':
case 'SQLSRV_SQLTYPE_IMAGE':
case 'SQLSRV_SQLTYPE_INT':
case 'SQLSRV_SQLTYPE_MONEY':
case 'SQLSRV_SQLTYPE_NVARCHAR':
case 'SQLSRV_SQLTYPE_NTEXT':
case 'SQLSRV_SQLTYPE_REAL':
case 'SQLSRV_SQLTYPE_SMALLDATETIME':
case 'SQLSRV_SQLTYPE_SMALLINT':
case 'SQLSRV_SQLTYPE_SMALLMONEY':
case 'SQLSRV_SQLTYPE_TEXT':
case 'SQLSRV_SQLTYPE_TIME':
case 'SQLSRV_SQLTYPE_TIMESTAMP':
case 'SQLSRV_SQLTYPE_TINYINT':
case 'SQLSRV_SQLTYPE_UNIQUEIDENTIFIER':
case 'SQLSRV_SQLTYPE_VARBINARY':
case 'SQLSRV_SQLTYPE_VARCHAR':
case 'SQLSRV_SQLTYPE_XML':
return constant( $sqlType );
break;
case 'SQLSRV_SQLTYPE_CHAR':
// our tests always use precision 5 for SQLSRV_SQLTYPE_CHAR
return SQLSRV_SQLTYPE_CHAR(5);
break;
case 'SQLSRV_SQLTYPE_DECIMAL':
// our tests always use precision 18 scale 5 for SQLSRV_SQLTYPE_DECIMAL
return SQLSRV_SQLTYPE_DECIMAL(18, 5);
break;
case 'SQLSRV_SQLTYPE_NCHAR':
// our tests always use precision 5 for SQLSRV_SQLTYPE_NCHAR
return SQLSRV_SQLTYPE_NCHAR(5);
break;
case 'SQLSRV_SQLTYPE_NUMERIC':
// our tests always use precision 10 scale 5 for SQLSRV_SQLTYPE_NUMERIC
return SQLSRV_SQLTYPE_NUMERIC(10, 5);
break;
default:
die( "get_sqlType_constant: Invalid SQL Type $sqlType\n" );
break;
}
}
function isDateTimeType( $sqlType )
{
return ($sqlType == 'SQLSRV_SQLTYPE_DATE' ||
$sqlType == 'SQLSRV_SQLTYPE_DATETIME' ||
$sqlType == 'SQLSRV_SQLTYPE_DATETIME2' ||
$sqlType == 'SQLSRV_SQLTYPE_DATETIMEOFFSET' ||
$sqlType == 'SQLSRV_SQLTYPE_SMALLDATETIME' ||
$sqlType == 'SQLSRV_SQLTYPE_TIME');
}
?>

View file

@ -32,8 +32,7 @@ AE\createTable($conn, $tbname, $colMetaArr);
// Create a Store Procedure
$spname = 'selectAllColumns';
$spSql = "CREATE PROCEDURE $spname (
@c1_int int OUTPUT, @c2_smallint smallint OUTPUT,
createProc($conn, $spname, "@c1_int int OUTPUT, @c2_smallint smallint OUTPUT,
@c3_tinyint tinyint OUTPUT, @c4_bit bit OUTPUT,
@c5_bigint bigint OUTPUT, @c6_decimal decimal(18,5) OUTPUT,
@c7_numeric numeric(10,5) OUTPUT, @c8_float float OUTPUT,
@ -41,8 +40,7 @@ $spSql = "CREATE PROCEDURE $spname (
@c11_datetime datetime OUTPUT, @c12_datetime2 datetime2 OUTPUT,
@c13_datetimeoffset datetimeoffset OUTPUT, @c14_time time OUTPUT,
@c15_char char(5) OUTPUT, @c16_varchar varchar(max) OUTPUT,
@c17_nchar nchar(5) OUTPUT, @c18_nvarchar nvarchar(max) OUTPUT) AS
SELECT @c1_int = c1_int, @c2_smallint = c2_smallint,
@c17_nchar nchar(5) OUTPUT, @c18_nvarchar nvarchar(max) OUTPUT", "SELECT @c1_int = c1_int, @c2_smallint = c2_smallint,
@c3_tinyint = c3_tinyint, @c4_bit = c4_bit,
@c5_bigint = c5_bigint, @c6_decimal = c6_decimal,
@c7_numeric = c7_numeric, @c8_float = c8_float,
@ -51,9 +49,7 @@ $spSql = "CREATE PROCEDURE $spname (
@c13_datetimeoffset = c13_datetimeoffset, @c14_time = c14_time,
@c15_char = c15_char, @c16_varchar = c16_varchar,
@c17_nchar = c17_nchar, @c18_nvarchar = c18_nvarchar
FROM $tbname";
sqlsrv_query($conn, $spSql);
FROM $tbname");
// Insert data
$inputs = array( "c1_int" => 2147483647,
"c2_smallint" => 32767,

View file

@ -0,0 +1,137 @@
--TEST--
Test for inserting and retrieving encrypted data of datetime types
--DESCRIPTION--
Bind output params using sqlsrv_prepare with all sql_type
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
require_once('AEData.inc');
date_default_timezone_set("Canada/Pacific");
$dataTypes = array("date", "datetime", "datetime2", "smalldatetime", "time", "datetimeoffset");
$directions = array("SQLSRV_PARAM_OUT", "SQLSRV_PARAM_INOUT");
// this is a list of implicit datatype conversion that SQL Server allows (https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine)
$compatList = array("date" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"),
"datetime" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"),
"datetime2" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"),
"smalldatetime" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DATE", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"),
"time" => array( "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_TIME", "SQLSRV_SQLTYPE_DATETIMEOFFSET", "SQLSRV_SQLTYPE_DATETIME2"),
"datetimeoffset" => array("SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIMEOFFSET") );
$conn = AE\connect();
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
$success = true;
// create table
$tbname = GetTempTableName("", false);
$colMetaArr = array(new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
if (AE\isColEncrypted()) {
// Create a Store Procedure
$spname = 'selectAllColumns';
createProc($conn, $spname, "@c_det $dataType OUTPUT, @c_rand $dataType OUTPUT", "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname");
}
// insert a row
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
$r;
$stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => $inputValues[0], $colMetaArr[1]->colName => $inputValues[1] ), $r);
if ($r === false) {
is_incompatible_types_error($dataType, "default type");
}
foreach($directions as $direction) {
echo "Testing as $direction:\n";
// test each SQLSRV_SQLTYPE_ constants
foreach ($sqlTypes as $sqlType) {
if (!AE\isColEncrypted()) {
$isCompatible = false;
foreach ($compatList[$dataType] as $compatType) {
if (stripos($compatType, $sqlType) !== false) {
$isCompatible = true;
}
}
// 22018 is the SQLSTATE for any incompatible conversion errors
if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) {
echo "$sqlType should be compatible with $dataType\n";
$success = false;
}
} else {
// skip unsupported datetime types
if (!isDateTimeType($sqlType)) {
$sqlTypeConstant = get_sqlType_constant($sqlType);
// Call store procedure
$outSql = AE\getCallProcSqlPlaceholders($spname, 2);
$c_detOut = '';
$c_randOut = '';
$stmt = sqlsrv_prepare( $conn, $outSql,
array(array( &$c_detOut, SQLSRV_PARAM_OUT, null, $sqlTypeConstant),
array(&$c_randOut, SQLSRV_PARAM_OUT, null, $sqlTypeConstant )));
if (!$stmt) {
die(print_r(sqlsrv_errors(), true));
}
sqlsrv_execute($stmt);
$errors = sqlsrv_errors();
if (empty($errors)) {
// SQLSRV_PHPTYPE_DATETIME not supported
echo "$dataType should not be compatible with any datetime type.\n";
$success = false;
}
}
sqlsrv_free_stmt($stmt);
}
}
}
if ($success) {
echo "Test successfully done.\n";
}
if (AE\isColEncrypted()) {
dropProc($conn, $spname);
}
dropTable($conn, $tbname);
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing date:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing datetime:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing datetime2:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing smalldatetime:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing time:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing datetimeoffset:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.

View file

@ -0,0 +1,187 @@
--TEST--
Test for inserting and retrieving encrypted data of numeric types
--DESCRIPTION--
Bind output params using sqlsrv_prepare with all sql_type
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
require_once('AEData.inc');
$dataTypes = array("bit", "tinyint", "smallint", "int", "bigint", "decimal(18,5)", "numeric(10,5)", "float", "real" );
$directions = array("SQLSRV_PARAM_OUT", "SQLSRV_PARAM_INOUT");
// this is a list of implicit datatype conversion that SQL Server allows (https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine)
$compatList = array("bit" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"),
"tinyint" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"),
"smallint" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"),
"int" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"),
"bigint" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP" ),
"decimal(18,5)" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"),
"numeric(10,5)" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT", "SQLSRV_SQLTYPE_TIMESTAMP"),
"float" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT"),
"real" => array( "SQLSRV_SQLTYPE_BINARY", "SQLSRV_SQLTYPE_VARBINARY", "SQLSRV_SQLTYPE_CHAR", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DATETIME", "SQLSRV_SQLTYPE_SMALLDATETIME", "SQLSRV_SQLTYPE_DECIMAL(18,5)", "SQLSRV_SQLTYPE_NUMERIC(10,5)", "SQLSRV_SQLTYPE_FLOAT", "SQLSRV_SQLTYPE_REAL", "SQLSRV_SQLTYPE_BIGINT", "SQLSRV_SQLTYPE_INT", "SQLSRV_SQLTYPE_SMALLINT", "SQLSRV_SQLTYPE_TINYINT", "SQLSRV_SQLTYPE_MONEY", "SQLSRV_SQLTYPE_SMALLMONEY", "SQLSRV_SQLTYPE_BIT"));
$epsilon = 0.0001;
$conn = AE\connect();
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
$success = true;
// create table
$tbname = GetTempTableName("", false);
$colMetaArr = array(new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// TODO: It's a good idea to test conversions between different datatypes when AE is off as well.
if (AE\isColEncrypted()) {
// Create a Store Procedure
$spname = 'selectAllColumns';
createProc($conn, $spname, "@c_det $dataType OUTPUT, @c_rand $dataType OUTPUT", "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname");
}
// insert a row
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
$r;
// convert input values to strings for decimals and numerics
if ($dataTypes == "decimal(18,5)" || $dataTypes == "numeric(10,5)") {
$stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => (string) $inputValues[0], $colMetaArr[1]->colName => (string) $inputValues[1] ), $r);
} else {
$stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => $inputValues[0], $colMetaArr[1]->colName => $inputValues[1] ), $r);
}
if ($r === false) {
is_incompatible_types_error($dataType, "default type");
}
foreach($directions as $direction) {
echo "Testing as $direction:\n";
// test each SQLSRV_SQLTYPE_ constants
foreach ($sqlTypes as $sqlType) {
if (!AE\isColEncrypted()) {
$isCompatible = false;
foreach ($compatList[$dataType] as $compatType) {
if (stripos($compatType, $sqlType) !== false) {
$isCompatible = true;
}
}
// 22018 is the SQLSTATE for any incompatible conversion errors
if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) {
echo "$sqlType should be compatible with $dataType\n";
$success = false;
}
} else {
// skip unsupported datetime types
if (!isDateTimeType($sqlType)) {
$sqlTypeConstant = get_sqlType_constant($sqlType);
// Call store procedure
$outSql = AE\getCallProcSqlPlaceholders($spname, 2);
if ($sqlType == 'SQLSRV_SQLTYPE_FLOAT' || $sqlType == 'SQLSRV_SQLTYPE_REAL') {
$c_detOut = 0.0;
$c_randOut = 0.0;
} else {
$c_detOut = 0;
$c_randOut = 0;
}
$stmt = sqlsrv_prepare($conn, $outSql,
array(array( &$c_detOut, constant($direction), null, $sqlTypeConstant),
array(&$c_randOut, constant($direction), null, $sqlTypeConstant)));
if (!$stmt) {
die(print_r(sqlsrv_errors(), true));
}
sqlsrv_execute($stmt);
$errors = sqlsrv_errors();
if (!empty($errors)) {
if (stripos("SQLSRV_SQLTYPE_" . $dataType, $sqlType) !== false) {
var_dump(sqlsrv_errors());
$success = false;
}
}
else {
if ($dataType == "float" || $dataType == "real") {
if (abs($c_detOut - $inputValues[0]) > $epsilon || abs($c_randOut - $inputValues[1]) > $epsilon) {
echo "Incorrect output retrieved for datatype $dataType and sqlType $sqlType:\n";
print(" c_det: " . $c_detOut . "\n");
print(" c_rand: " . $c_randOut . "\n");
$success = false;
}
} else {
if ($c_detOut != $inputValues[0] || $c_randOut != $inputValues[1]) {
echo "Incorrect output retrieved for datatype $dataType and sqlType $sqlType:\n";
print(" c_det: " . $c_detOut . "\n");
print(" c_rand: " . $c_randOut . "\n");
$success = false;
}
}
}
sqlsrv_free_stmt($stmt);
}
}
}
}
if (AE\isColEncrypted()) {
dropProc($conn, $spname);
}
if ($success) {
echo "Test successfully done.\n";
}
dropTable($conn, $tbname);
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing bit:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing tinyint:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing smallint:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing int:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing bigint:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing decimal(18,5):
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing numeric(10,5):
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing float:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing real:
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.

View file

@ -0,0 +1,137 @@
--TEST--
Test for inserting and retrieving encrypted data of string types
--DESCRIPTION--
Bind output params using sqlsrv_prepare with all sql_type
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
--FILE--
<?php
require_once('MsCommon.inc');
require_once('AEData.inc');
$dataTypes = array("char(5)", "varchar(max)", "nchar(5)", "nvarchar(max)");
$directions = array("SQLSRV_PARAM_OUT", "SQLSRV_PARAM_INOUT");
// this is a list of implicit datatype conversion that SQL Server allows (https://docs.microsoft.com/en-us/sql/t-sql/data-types/data-type-conversion-database-engine)
$compatList = array("char(5)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"),
"varchar(max)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"),
"nchar(5)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"),
"nvarchar(max)" => array( "SQLSRV_SQLTYPE_CHAR(5)", "SQLSRV_SQLTYPE_VARCHAR", "SQLSRV_SQLTYPE_NCHAR(5)", "SQLSRV_SQLTYPE_NVARCHAR", "SQLSRV_SQLTYPE_DECIMAL", "SQLSRV_SQLTYPE_NUMERIC", "SQLSRV_SQLTYPE_NTEXT", "SQLSRV_SQLTYPE_TEXT", "SQLSRV_SQLTYPE_XML"));
$conn = AE\connect();
foreach ($dataTypes as $dataType) {
echo "\nTesting $dataType:\n";
$success = true;
// create table
$tbname = GetTempTableName("", false);
$colMetaArr = array(new AE\ColumnMeta($dataType, "c_det"), new AE\ColumnMeta($dataType, "c_rand", null, false));
AE\createTable($conn, $tbname, $colMetaArr);
// TODO: It's a good idea to test conversions between different datatypes when AE is off as well.
if (AE\isColEncrypted()) {
// Create a Store Procedure
$spname = 'selectAllColumns';
createProc($conn, $spname, "@c_det $dataType OUTPUT, @c_rand $dataType OUTPUT", "SELECT @c_det = c_det, @c_rand = c_rand FROM $tbname");
}
// insert a row
$inputValues = array_slice(${explode("(", $dataType)[0] . "_params"}, 1, 2);
$r;
$stmt = AE\insertRow($conn, $tbname, array( $colMetaArr[0]->colName => $inputValues[0], $colMetaArr[1]->colName => $inputValues[1] ), $r);
if ($r === false) {
is_incompatible_types_error($dataType, "default type");
}
foreach($directions as $direction) {
echo "Testing as $direction:\n";
// test each SQLSRV_SQLTYPE_ constants
foreach ($sqlTypes as $sqlType) {
if (!AE\isColEncrypted()) {
$isCompatible = false;
foreach ($compatList[$dataType] as $compatType) {
if (stripos($compatType, $sqlType) !== false) {
$isCompatible = true;
}
}
// 22018 is the SQLSTATE for any incompatible conversion errors
if ($isCompatible && sqlsrv_errors()[0]['SQLSTATE'] == 22018) {
echo "$sqlType should be compatible with $dataType\n";
$success = false;
}
} else {
// skip unsupported datetime types
if (!isDateTimeType($sqlType)) {
$sqlTypeConstant = get_sqlType_constant($sqlType);
// Call store procedure
$outSql = AE\getCallProcSqlPlaceholders($spname, 2);
$c_detOut = '';
$c_randOut = '';
$stmt = sqlsrv_prepare($conn, $outSql,
array(array(&$c_detOut, SQLSRV_PARAM_INOUT, null, $sqlTypeConstant),
array(&$c_randOut, SQLSRV_PARAM_INOUT, null, $sqlTypeConstant)));
if (!$stmt) {
die(print_r(sqlsrv_errors(), true));
}
sqlsrv_execute($stmt);
$errors = sqlsrv_errors();
if (!empty($errors) ) {
if (stripos("SQLSRV_SQLTYPE_" . $dataType, $sqlType) !== false) {
var_dump(sqlsrv_errors());
$success = false;
}
}
else
{
if ($c_detOut != $inputValues[0] || $c_randOut != $inputValues[1]) {
echo "Incorrect output retrieved for datatype $dataType and sqlType $sqlType:\n";
print(" c_det: " . $c_detOut . "\n");
print(" c_rand: " . $c_randOut . "\n");
$success = false;
}
}
sqlsrv_free_stmt($stmt);
}
}
}
}
if (AE\isColEncrypted()) {
dropProc($conn, $spname);
}
if ($success) {
echo "Test successfully done.\n";
}
dropTable($conn, $tbname);
}
sqlsrv_close($conn);
?>
--EXPECT--
Testing char(5):
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing varchar(max):
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing nchar(5):
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.
Testing nvarchar(max):
Testing as SQLSRV_PARAM_OUT:
Testing as SQLSRV_PARAM_INOUT:
Test successfully done.