php-sqlsrv/test/functional/sqlsrv/0065.phpt

282 lines
8.1 KiB
Plaintext
Raw Normal View History

2017-05-03 17:05:26 +02:00
--TEST--
inserting and retrieving UTF-8 text.
--SKIPIF--
<?php require('skipif_versions_old.inc'); ?>
2017-05-03 17:05:26 +02:00
--FILE--
<?php
sqlsrv_configure('WarningsReturnAsErrors', 0);
sqlsrv_configure('LogSeverity', SQLSRV_LOG_SEVERITY_ALL);
2017-05-03 17:05:26 +02:00
// For testing in Azure, can not switch databases
require_once('MsCommon.inc');
$c = AE\connect();
$tableName = 'utf8test';
$columns = array(new AE\ColumnMeta('varchar(100)', 'c1'),
new AE\ColumnMeta('nvarchar(100)', 'c2'),
new AE\ColumnMeta('nvarchar(max)', 'c3'));
$stmt = AE\createTable($c, $tableName, $columns);
if (!$stmt) {
fatalError("Failed to create table $tableName\n");
2017-05-03 17:05:26 +02:00
}
$utf8 = "Şơмė śäოрŀề ΆŚĈĨİ-ť℮×ŧ";
$params = array(array(&$utf8, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')),
array(&$utf8, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')),
array(&$utf8, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')));
$insertSql = "INSERT INTO $tableName (c1, c2, c3) VALUES (?,?,?)";
$s = AE\executeQueryParams($c, $insertSql, $params);
2017-05-03 17:05:26 +02:00
$query = "DROP PROCEDURE IntDoubleProc; DROP PROCEDURE Utf8OutProc; DROP PROCEDURE Utf8OutWithResultsetProc; DROP PROCEDURE Utf8InOutProc; DROP TABLE Utf8TestTable;";
$s = sqlsrv_query($c, $query);
2017-05-03 17:05:26 +02:00
$create_proc = <<<PROC
CREATE PROCEDURE Utf8OutProc
@param nvarchar(25) OUTPUT
AS
BEGIN
set @param = convert(nvarchar(25), 0x5E01A1013C04170120005B01E400DD1040044001C11E200086035A010801280130012D0065012E21D7006701);
END;
PROC;
$s = sqlsrv_query($c, $create_proc);
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
$createProc = "CREATE PROCEDURE Utf8OutWithResultsetProc @param NVARCHAR(25) OUTPUT AS BEGIN SELECT c1, c2, c3 FROM $tableName SET @param = CONVERT(NVARCHAR(25), 0x5E01A1013C04170120005B01E400DD1040044001C11E200086035A010801280130012D0065012E21D7006701); END";
$s = sqlsrv_query($c, $createProc);
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
$createProc = "CREATE PROCEDURE Utf8InOutProc @param NVARCHAR(25) OUTPUT AS BEGIN SET @param = CONVERT(NVARCHAR(25), 0x6001E11EDD10130120006101E200DD1040043A01BB1E2000C5005A01C700CF0007042D006501BF1E45046301); END";
$s = sqlsrv_query($c, $createProc);
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
$createProc = "CREATE PROCEDURE IntDoubleProc @param INT OUTPUT AS BEGIN SET @param = @param + @param; END;";
$s = sqlsrv_query($c, $createProc);
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
$s = sqlsrv_query($c, "SELECT c1, c2, c3 FROM $tableName");
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
if (sqlsrv_fetch($s) === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
$t = sqlsrv_get_field($s, 0, SQLSRV_PHPTYPE_STRING('utf-8'));
if ($t === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
2018-01-05 00:21:10 +01:00
// If connected with AE, $t may be different in Windows and other platforms
// this is a workaround for now -- to make sure there are some '?' in $t
if (!AE\isColEncrypted() && $t !== "So?e sä???? ?SCII-te×t") {
die("varchar(100) \'$t\' doesn't match So?e sä???? ?SCII-te×t");
} else {
$arr = explode('?', $t);
// in Alpine Linux, data returned is diffferent with always encrypted:
// something like '**** *ä**** *****-**×*'
// instead of '?', it replaces inexact conversions with asterisks
// reference: read the ICONV section in
// https://wiki.musl-libc.org/functional-differences-from-glibc.html
2018-01-05 00:21:10 +01:00
if (count($arr) == 1) {
// this means there is no question mark in $t
// then try to find a substring of some asterisks
$asterisks = '****';
if(strpos($t, '****') === false) {
die("varchar(100) value \'$t\' is unexpected");
}
2018-01-05 00:21:10 +01:00
}
2017-05-03 17:05:26 +02:00
}
$t = sqlsrv_get_field($s, 1, SQLSRV_PHPTYPE_STRING('utf-8'));
if ($t === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
2018-01-04 19:18:43 +01:00
if ($t !== $utf8) {
die("nvarchar(100) doesn't match the inserted UTF-8 text.");
2017-05-03 17:05:26 +02:00
}
$t = sqlsrv_get_field($s, 2, SQLSRV_PHPTYPE_STRING('utf-8'));
if ($t === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
2018-01-04 19:18:43 +01:00
if ($t !== $utf8) {
die("nvarchar(max) doesn't match the inserted UTF-8 text.");
2017-05-03 17:05:26 +02:00
}
sqlsrv_free_stmt($s);
2017-05-03 17:05:26 +02:00
// test proc to baseline with
$t = 1;
$sqlType = AE\isColEncrypted() ? SQLSRV_SQLTYPE_INT : null;
2017-05-03 17:05:26 +02:00
$s = sqlsrv_query($c, "{call IntDoubleProc(?)}", array(array(&$t, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_INT, $sqlType)));
2017-05-03 17:05:26 +02:00
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
if ($t != 2) {
die("Incorrect results for IntDoubleProc");
2017-05-03 17:05:26 +02:00
}
$t = "";
// output param with immediate conversion
$s = sqlsrv_query(
$c,
"{call Utf8OutProc(?)}",
array(array(&$t, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_NVARCHAR(50)))
);
2017-05-03 17:05:26 +02:00
if ($s === false) {
2017-05-03 17:05:26 +02:00
echo "{call Utf8OutProc(?)} failed\n";
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
2018-01-04 19:18:43 +01:00
if ($t !== $utf8) {
die("Incorrect results from Utf8OutProc\n");
2017-05-03 17:05:26 +02:00
}
$t = "";
$s = sqlsrv_query(
$c,
"{call Utf8OutWithResultsetProc(?)}",
array(array(&$t, SQLSRV_PARAM_OUT, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_NVARCHAR(50)))
);
2017-05-03 17:05:26 +02:00
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
// retrieve all the results
while (sqlsrv_next_result($s));
2017-05-03 17:05:26 +02:00
2018-01-04 19:18:43 +01:00
if ($t !== $utf8) {
die("Incorrect results from Utf8OutWithResultsetProc\n");
2017-05-03 17:05:26 +02:00
}
// another set of UTF-8 text to try
$utf8 = "Šỡოē šâოрĺẻ ÅŚÇÏЇ-ťếхţ";
// this input string is smaller than the output size for testing
$t = "This is a test.";
// this works
$s = sqlsrv_query(
$c,
"{call Utf8InOutProc(?)}",
array(array(&$t, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_NVARCHAR(25)))
);
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
2018-01-04 19:18:43 +01:00
if ($t !== $utf8) {
die("Incorrect results from Utf8InOutProc 1\n");
2017-05-03 17:05:26 +02:00
}
$t = "This is a longer test that exceeds the returned values buffer size so that we can test an input buffer size larger than the output buffer size.";
// this returns an error 22001, meaning that the string is too large
$s = sqlsrv_query(
$c,
"{call Utf8InOutProc(?)}",
array(array(&$t, SQLSRV_PARAM_INOUT, SQLSRV_PHPTYPE_STRING('utf-8'), SQLSRV_SQLTYPE_NVARCHAR(25)))
);
if ($s !== false) {
die("Should have failed since the string is too long");
2017-05-03 17:05:26 +02:00
}
print_r(sqlsrv_errors());
2017-05-03 17:05:26 +02:00
$t = pack('H*', '7a61cc86c7bdceb2f18fb3bf');
2017-05-03 17:05:26 +02:00
$params = array(array(&$t, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')),
array(&$t, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')),
array(&$t, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')));
$insertSql = "INSERT INTO $tableName (c1, c2, c3) VALUES (?,?,?)";
$s = AE\executeQueryParams($c, $insertSql, $params);
2017-05-03 17:05:26 +02:00
print_r(sqlsrv_errors());
$s = sqlsrv_query($c, "SELECT c1, c2, c3 FROM $tableName");
if ($s === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
if (sqlsrv_fetch($s) === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
// move to the second row
if (sqlsrv_fetch($s) === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
$u = sqlsrv_get_field($s, 1, SQLSRV_PHPTYPE_STRING('utf-8'));
if ($u === false) {
die(print_r(sqlsrv_errors(), true));
2017-05-03 17:05:26 +02:00
}
if ($t !== $u) {
die("Round trip failed.");
2017-05-03 17:05:26 +02:00
}
// $t is an invalid utf-8 string, expect the procedure to fail
$t = pack('H*', 'ffffffff');
2017-05-03 17:05:26 +02:00
$sqlType =
$params = array(array(&$t, SQLSRV_PARAM_IN, SQLSRV_PHPTYPE_STRING('utf-8')));
$query = "{call Utf8InOutProc(?)}";
$s = AE\executeQueryParams($c, $query, $params, true, "no error from an invalid utf-8 string");
dropTable($c, $tableName);
2017-05-03 17:05:26 +02:00
sqlsrv_close($c);
2017-05-03 17:05:26 +02:00
echo "Test succeeded.\n";
?>
--EXPECTF--
Array
(
[0] => Array
(
[0] => 22001
[SQLSTATE] => 22001
[1] => 0
[code] => 0
[2] => %SString data, right truncation
[message] => %SString data, right truncation
)
)
Array
(
[0] => Array
(
[0] => IMSSP
[SQLSTATE] => IMSSP
[1] => -40
[code] => -40
[2] => An error occurred translating string for input param 1 to UCS-2: %a
[message] => An error occurred translating string for input param 1 to UCS-2: %a
)
)
Test succeeded.